解决怎样监听Activity切换
本篇博文在我之前的博文中已经提到了,可是监听Activity切换又能够作为一个单独的内容来叙述,因此这里又单独拿了出来进行赘述。
Activity的切换无非有两种。第一种:启动或者创建一个新的Activity;另外一种:唤醒后台执行的Activity。
因此假设我们可以成功监听到启动或者创建一个Activity,或者唤醒Activity我们就基本完毕了Activity的切换的监听。
在源代码/frameworks/base/core/java/android/app文件夹下ActivityThread.java中为我们提供了这样一个方法来帮助我们完毕对Activity启动、创建、销毁、暂停、停止。唤醒等生命周期的监听。
- public void handleMessage(Message msg) {
- if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
- switch (msg.what) {
- case LAUNCH_ACTIVITY: {
- /// M: enable profiling @{
- if ( true == mEnableAppLaunchLog && !mIsUserBuild && false == mTraceEnabled ) {
- try {
- FileInputStream fprofsts_in = new FileInputStream("/proc/mtprof/status");
- if ( fprofsts_in.read()== '3' ) {
- Log.v(TAG, "start Profiling for empty process");
- mTraceEnabled = true;
- Debug.startMethodTracing("/data/data/applaunch"); //applaunch.trace
- }
- } catch (FileNotFoundException e) {
- Slog.e(TAG, "mtprof entry can not be found", e);
- } catch (java.io.IOException e) {
- Slog.e(TAG, "mtprof entry open failed", e);
- }
- }
- /// @}
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "activityStart"); /// M: add TRACE_TAG_PERF for performance debug
- ActivityClientRecord r = (ActivityClientRecord)msg.obj;
- r.packageInfo = getPackageInfoNoCheck(
- r.activityInfo.applicationInfo, r.compatInfo);
- handleLaunchActivity(r, null);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF); /// M: add TRACE_TAG_PERF for performance debug
- } break;
- case RELAUNCH_ACTIVITY: {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
- ActivityClientRecord r = (ActivityClientRecord)msg.obj;
- handleRelaunchActivity(r);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- } break;
- case PAUSE_ACTIVITY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
- maybeSnapshot();
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case PAUSE_ACTIVITY_FINISHING:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case STOP_ACTIVITY_SHOW:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- handleStopActivity((IBinder)msg.obj, true, msg.arg2);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case STOP_ACTIVITY_HIDE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- handleStopActivity((IBinder)msg.obj, false, msg.arg2);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case SHOW_WINDOW:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
- handleWindowVisibility((IBinder)msg.obj, true);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case HIDE_WINDOW:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
- handleWindowVisibility((IBinder)msg.obj, false);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case RESUME_ACTIVITY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "activityResume"); /// M: add TRACE_TAG_PERF for performance debug
- handleResumeActivity((IBinder)msg.obj, true,
- msg.arg1 != 0, true);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF); /// M: add TRACE_TAG_PERF for performance debug
- break;
- case SEND_RESULT:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
- handleSendResult((ResultData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case DESTROY_ACTIVITY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
- handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
- msg.arg2, false);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case BIND_APPLICATION:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
- AppBindData data = (AppBindData)msg.obj;
- handleBindApplication(data);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case EXIT_APPLICATION:
- if (mInitialApplication != null) {
- mInitialApplication.onTerminate();
- }
- Looper.myLooper().quit();
- break;
- case NEW_INTENT:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
- handleNewIntent((NewIntentData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case RECEIVER:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
- handleReceiver((ReceiverData)msg.obj);
- maybeSnapshot();
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case CREATE_SERVICE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
- handleCreateService((CreateServiceData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case BIND_SERVICE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
- handleBindService((BindServiceData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case UNBIND_SERVICE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
- handleUnbindService((BindServiceData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case SERVICE_ARGS:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
- handleServiceArgs((ServiceArgsData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case STOP_SERVICE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
- handleStopService((IBinder)msg.obj);
- maybeSnapshot();
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case REQUEST_THUMBNAIL:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
- handleRequestThumbnail((IBinder)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case CONFIGURATION_CHANGED:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
- mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
- handleConfigurationChanged((Configuration)msg.obj, null);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case CLEAN_UP_CONTEXT:
- ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
- cci.context.performFinalCleanup(cci.who, cci.what);
- break;
- case GC_WHEN_IDLE:
- scheduleGcIdler();
- break;
- case DUMP_SERVICE:
- handleDumpService((DumpComponentInfo)msg.obj);
- break;
- case LOW_MEMORY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
- handleLowMemory();
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case ACTIVITY_CONFIGURATION_CHANGED:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
- handleActivityConfigurationChanged((IBinder)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case PROFILER_CONTROL:
- handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
- break;
- case CREATE_BACKUP_AGENT:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
- handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case DESTROY_BACKUP_AGENT:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
- handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case SUICIDE:
- Process.killProcess(Process.myPid());
- break;
- case REMOVE_PROVIDER:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
- completeRemoveProvider((ProviderRefCount)msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case ENABLE_JIT:
- ensureJitEnabled();
- break;
- case DISPATCH_PACKAGE_BROADCAST:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
- handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case SCHEDULE_CRASH:
- throw new RemoteServiceException((String)msg.obj);
- case DUMP_HEAP:
- handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
- break;
- case DUMP_ACTIVITY:
- handleDumpActivity((DumpComponentInfo)msg.obj);
- break;
- case DUMP_PROVIDER:
- handleDumpProvider((DumpComponentInfo)msg.obj);
- break;
- case SLEEPING:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
- handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case SET_CORE_SETTINGS:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
- handleSetCoreSettings((Bundle) msg.obj);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case UPDATE_PACKAGE_COMPATIBILITY_INFO:
- handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
- break;
- case TRIM_MEMORY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
- handleTrimMemory(msg.arg1);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case UNSTABLE_PROVIDER_DIED:
- handleUnstableProviderDied((IBinder)msg.obj, false);
- break;
- case REQUEST_ASSIST_CONTEXT_EXTRAS:
- handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
- break;
- case TRANSLUCENT_CONVERSION_COMPLETE:
- handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
- break;
- case INSTALL_PROVIDER:
- handleInstallProvider((ProviderInfo) msg.obj);
- break;
- }
- if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
- /// M: ActivityThread log enhancement @{
- if(!mIsUserBuild && isDebuggableMessage(msg.what)){
- Slog.d(TAG, codeToString(msg.what) + " handled "
- + ": " + msg.arg1 + " / " + msg.obj);
- }
- /// @}
- }
这里我们能够看到。我们能够通过监听LAUNCH_ACTIVITY,RESUME_ACTIVITY等来推断Activity的切换,因此我们能够将通过在ActivityThread.java中将获得顶层栈栈顶Activity的方法在这里调用以实现我们的需求。
那么这样是否可以完毕我们的需求呢?
答案是否定的。即使我们可以编译通过,可是在我们測试观察log的时候。并不能得到当前处于活动状态的Activity。那么为什么会出现这样的情况呢?
通过观察log我们发现,这里我们须要GET_TASK权限,当然我们能够通过加入权限的方式,但这样有风险,那么有没有一个更可靠的方式呢。
依然是通过观察log,我们发现Android系统会使用一个ActivityClientRecoder类来记录Activity的信息,而这个类在ActivityThread中也得到了应用。因此我们能够通过得到ActivityClientRecoder的对象r来获得Activity对象,在通过Activity对象的getComponent()来得到ComponentName的对象。在ComponentName对象中便封装了应用程序包名和当前处于活动状态的Activity。
详细实现方式这里不再详细赘述。仅仅是提供获取Activity信息的部分代码进行简单分析一下,大家能够參考一下。
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Activity a=r.parent;
ComponentName c=a.getComponentName();
String package=c.mPackage;
String className=c.mClass;StrSt
此外另一种备用的方式,就是我们能够通过得到当前处于活动状态进程信息来推断当前处以活动状态的进程。
实现方式例如以下:
- final ActivityManager am = (ActivityManager)mAppContextImpl.getSystemService(Context.ACTIVITY_SERVICE);
- List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
- if (list.size() != 0) {
- RunningAppProcessInfo topRunningProcess = list.get(0);
- if(topRunningProcess.processName.equals("com.android.xx.xxxxx")){
- return true;
- }
- }
- return false;
解决怎样监听Activity切换的更多相关文章
- 解决如何监听Activity切换
本篇博文在我之前的博文中已经提到了,但是监听Activity切换又可以作为一个单独的内容来叙述,因此这里又单独拿了出来进行赘述. Activity的切换无非有两种,第一种:启动或者创建一个新的Acti ...
- ImageView 会盖掉ScrollView的OnTouchListener,监听Activity的手势
当Activity的高度不够滑动的时候,ImageView会盖掉ScrollView的OnTouchListener监听. 这个时候须要设置Activity的(或者想直接监听Activity的手势也能 ...
- Android - 监听Activity点击无效
监听Activity点击无效 本文地址: http://blog.csdn.net/caroline_wendy Activity须要先在Manifest注冊,才干在app中使用; Manifest: ...
- (原)android中的动画(三)之动画监听&页面切换动画
1.动画也可以设置监听事件,例如在动画结束时需要执行某操作 把要执行的代码写在onAnimationEnd()回调方法中即可: anim.setAnimationListener(new Animat ...
- 解决Oracle监听错误的一种办法
1:事出有因 安装oracle数据库,默认安装的是orcl数据库,安装完成后查看了一下字符集是gbk的,由于业务需要al32utf8的字符集,所以需要修改字符集,但是修改却无效.于是就删除了默认的or ...
- laydate 监听日期切换
```` //日期范围 laydate.render({ elem: '#Time', range: "至", max: gitData() ,done: function(val ...
- app进入后台之后接收到通知,点进去进入新的页面,再次进入后台,再点击通知进入页面(,两次通过通知进入的页面,创建了两次,会多一个页面,)解决办法监听
在点击通知进入的页面的 //UIApplicationWillResignActiveNotification是app即将进入后台的方法 //增加监听使它在进入后台之前pop上一个页面 - (void ...
- 解决visualsvn监听ip 错误的问题
系统重启+休眠之类的,弄几次,莫名其妙的svn就连接不上了, 有时候启动不起,有时候是启动连接不上,发现监听的ip错了 TCP [::]:443 [::]:0 ...
- sencha touch 监听视图切换动画(animation)
var animation = this.getLayout().getAnimation(); //添加监听 animation.on({ scope: this, animationend: 'o ...
随机推荐
- MongoDb C# 驱动操作示例
c#操作mongo数据库 驱动采用http://www.oschina.net/p/mongo-csharp-driver C#驱动的基本数据库连接,增删改查操作 //定义对象 public clas ...
- poj 3708 Recurrent Function
Recurrent Function Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1233 Accepted: 336 ...
- build android on macOS
http://blog.csdn.net/loften_93663469/article/details/51503293 @import url(http://i.cnblogs.com/Load. ...
- Perl语言入门--4--列表
1.列表也是数组的形式:(1,'a',2,3,4) 元素可以是任意类型,变量,表达式 2.空列表:() 单元素列表:(2) .与值2不同 qw(1 $a str) #qw是用空格作为分隔符,元素 ...
- ecshop二次开发系统缓存优化之扩展数据缓存的必要性与方法
1.扩展数据缓存的必要性 大家都知道ecshop系统使用的是静态模板缓存,在后台可以设置静态模板的缓存时间,只要缓存不过期,用户访问页面就相当于访问静态页面,速度可想而知,看似非常完美,但是ecsho ...
- 多协议底层攻击工具Yesinia
多协议底层攻击工具Yesinia Yesinia是一款底层协议攻击工具.它提供多种运行模式,如终端文本模式.GTK图形模式.NCurses模式.守护进程模式.它利用各种底层协议的漏洞实施攻击,支持 ...
- java基础第三篇
6.Java 中的容器(重点) a.变量:变量是一个容器,它存储的单个值 //int i=3; 1.局部变量:定义在方法中,没有默认值 2.成员变量:定义在类中方法外,这个事物的属性(特征)定义为成员 ...
- RabbitMQ 最常用的三大模式
目录 Direct 模式 Topic 模式 Fanout 模式 Direct 模式 所有发送到 Direct Exchange 的消息被转发到 RouteKey 中指定的 Queue. Direct ...
- 朱子奇- 精算师,Tailorwoods创始人 | 到「在行」来约见我
朱子奇- 精算师,Tailorwoods创始人 | 到「在行」来约见我 Tailorwoods
- 邁向IT專家成功之路的三十則鐵律 鐵律十九:IT人待業之道-寬心
說來很多人可能不相信,筆者從來不把失業當作是一件嚴重的事,相反的我會把它當作是一個很好的轉機.針對一個隨時做好準備的IT人,三個月或半年沒有上班完全沒有甚麼好擔心的.只是如何善用待業的時間,說實在的真 ...