本篇博文在我之前的博文中已经提到了,但是监听Activity切换又可以作为一个单独的内容来叙述,因此这里又单独拿了出来进行赘述。

Activity的切换无非有两种,第一种:启动或者创建一个新的Activity;第二种:唤醒后台运行的Activity。因此如果我们能够成功监听到启动或者创建一个Activity,或者唤醒Activity我们就基本完成了Activity的切换的监听。

在源码/frameworks/base/core/java/android/app目录下ActivityThread.java中为我们提供了这样一个方法来帮助我们完成对Activity启动、创建、销毁、暂停、停止,唤醒等生命周期的监听。

  1. public void handleMessage(Message msg) {
  2. if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
  3. switch (msg.what) {
  4. case LAUNCH_ACTIVITY: {
  5. /// M: enable profiling @{
  6. if ( true == mEnableAppLaunchLog && !mIsUserBuild && false == mTraceEnabled ) {
  7. try {
  8. FileInputStream fprofsts_in = new FileInputStream("/proc/mtprof/status");
  9. if ( fprofsts_in.read()== '3' ) {
  10. Log.v(TAG, "start Profiling for empty process");
  11. mTraceEnabled = true;
  12. Debug.startMethodTracing("/data/data/applaunch"); //applaunch.trace
  13. }
  14. } catch (FileNotFoundException e) {
  15. Slog.e(TAG, "mtprof entry can not be found", e);
  16. } catch (java.io.IOException e) {
  17. Slog.e(TAG, "mtprof entry open failed", e);
  18. }
  19. }
  20. /// @}
  21. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "activityStart"); /// M: add TRACE_TAG_PERF for performance debug
  22. ActivityClientRecord r = (ActivityClientRecord)msg.obj;
  23. r.packageInfo = getPackageInfoNoCheck(
  24. r.activityInfo.applicationInfo, r.compatInfo);
  25. handleLaunchActivity(r, null);
  26. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF); /// M: add TRACE_TAG_PERF for performance debug
  27. } break;
  28. case RELAUNCH_ACTIVITY: {
  29. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
  30. ActivityClientRecord r = (ActivityClientRecord)msg.obj;
  31. handleRelaunchActivity(r);
  32. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  33. } break;
  34. case PAUSE_ACTIVITY:
  35. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
  36. handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
  37. maybeSnapshot();
  38. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  39. break;
  40. case PAUSE_ACTIVITY_FINISHING:
  41. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
  42. handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
  43. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  44. break;
  45. case STOP_ACTIVITY_SHOW:
  46. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
  47. handleStopActivity((IBinder)msg.obj, true, msg.arg2);
  48. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  49. break;
  50. case STOP_ACTIVITY_HIDE:
  51. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
  52. handleStopActivity((IBinder)msg.obj, false, msg.arg2);
  53. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  54. break;
  55. case SHOW_WINDOW:
  56. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
  57. handleWindowVisibility((IBinder)msg.obj, true);
  58. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  59. break;
  60. case HIDE_WINDOW:
  61. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
  62. handleWindowVisibility((IBinder)msg.obj, false);
  63. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  64. break;
  65. case RESUME_ACTIVITY:
  66. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "activityResume"); /// M: add TRACE_TAG_PERF for performance debug
  67. handleResumeActivity((IBinder)msg.obj, true,
  68. msg.arg1 != 0, true);
  69. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF); /// M: add TRACE_TAG_PERF for performance debug
  70. break;
  71. case SEND_RESULT:
  72. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
  73. handleSendResult((ResultData)msg.obj);
  74. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  75. break;
  76. case DESTROY_ACTIVITY:
  77. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
  78. handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
  79. msg.arg2, false);
  80. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  81. break;
  82. case BIND_APPLICATION:
  83. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
  84. AppBindData data = (AppBindData)msg.obj;
  85. handleBindApplication(data);
  86. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  87. break;
  88. case EXIT_APPLICATION:
  89. if (mInitialApplication != null) {
  90. mInitialApplication.onTerminate();
  91. }
  92. Looper.myLooper().quit();
  93. break;
  94. case NEW_INTENT:
  95. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
  96. handleNewIntent((NewIntentData)msg.obj);
  97. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  98. break;
  99. case RECEIVER:
  100. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
  101. handleReceiver((ReceiverData)msg.obj);
  102. maybeSnapshot();
  103. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  104. break;
  105. case CREATE_SERVICE:
  106. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
  107. handleCreateService((CreateServiceData)msg.obj);
  108. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  109. break;
  110. case BIND_SERVICE:
  111. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
  112. handleBindService((BindServiceData)msg.obj);
  113. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  114. break;
  115. case UNBIND_SERVICE:
  116. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
  117. handleUnbindService((BindServiceData)msg.obj);
  118. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  119. break;
  120. case SERVICE_ARGS:
  121. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
  122. handleServiceArgs((ServiceArgsData)msg.obj);
  123. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  124. break;
  125. case STOP_SERVICE:
  126. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
  127. handleStopService((IBinder)msg.obj);
  128. maybeSnapshot();
  129. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  130. break;
  131. case REQUEST_THUMBNAIL:
  132. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
  133. handleRequestThumbnail((IBinder)msg.obj);
  134. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  135. break;
  136. case CONFIGURATION_CHANGED:
  137. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
  138. mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
  139. handleConfigurationChanged((Configuration)msg.obj, null);
  140. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  141. break;
  142. case CLEAN_UP_CONTEXT:
  143. ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
  144. cci.context.performFinalCleanup(cci.who, cci.what);
  145. break;
  146. case GC_WHEN_IDLE:
  147. scheduleGcIdler();
  148. break;
  149. case DUMP_SERVICE:
  150. handleDumpService((DumpComponentInfo)msg.obj);
  151. break;
  152. case LOW_MEMORY:
  153. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
  154. handleLowMemory();
  155. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  156. break;
  157. case ACTIVITY_CONFIGURATION_CHANGED:
  158. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
  159. handleActivityConfigurationChanged((IBinder)msg.obj);
  160. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  161. break;
  162. case PROFILER_CONTROL:
  163. handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
  164. break;
  165. case CREATE_BACKUP_AGENT:
  166. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
  167. handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
  168. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  169. break;
  170. case DESTROY_BACKUP_AGENT:
  171. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
  172. handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
  173. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  174. break;
  175. case SUICIDE:
  176. Process.killProcess(Process.myPid());
  177. break;
  178. case REMOVE_PROVIDER:
  179. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
  180. completeRemoveProvider((ProviderRefCount)msg.obj);
  181. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  182. break;
  183. case ENABLE_JIT:
  184. ensureJitEnabled();
  185. break;
  186. case DISPATCH_PACKAGE_BROADCAST:
  187. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
  188. handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
  189. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  190. break;
  191. case SCHEDULE_CRASH:
  192. throw new RemoteServiceException((String)msg.obj);
  193. case DUMP_HEAP:
  194. handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
  195. break;
  196. case DUMP_ACTIVITY:
  197. handleDumpActivity((DumpComponentInfo)msg.obj);
  198. break;
  199. case DUMP_PROVIDER:
  200. handleDumpProvider((DumpComponentInfo)msg.obj);
  201. break;
  202. case SLEEPING:
  203. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
  204. handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
  205. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  206. break;
  207. case SET_CORE_SETTINGS:
  208. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
  209. handleSetCoreSettings((Bundle) msg.obj);
  210. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  211. break;
  212. case UPDATE_PACKAGE_COMPATIBILITY_INFO:
  213. handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
  214. break;
  215. case TRIM_MEMORY:
  216. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
  217. handleTrimMemory(msg.arg1);
  218. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  219. break;
  220. case UNSTABLE_PROVIDER_DIED:
  221. handleUnstableProviderDied((IBinder)msg.obj, false);
  222. break;
  223. case REQUEST_ASSIST_CONTEXT_EXTRAS:
  224. handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
  225. break;
  226. case TRANSLUCENT_CONVERSION_COMPLETE:
  227. handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
  228. break;
  229. case INSTALL_PROVIDER:
  230. handleInstallProvider((ProviderInfo) msg.obj);
  231. break;
  232. }
  233. if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
  234. /// M: ActivityThread log enhancement @{
  235. if(!mIsUserBuild && isDebuggableMessage(msg.what)){
  236. Slog.d(TAG, codeToString(msg.what) + " handled "
  237. + ": " + msg.arg1 + " / " + msg.obj);
  238. }
  239. /// @}
  240. }

这里我们可以看到,我们可以通过监听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

此外还有一种备用的方式,就是我们可以通过得到当前处于活动状态进程信息来判断当前处以活动状态的进程。

实现方式如下:

  1. final ActivityManager am = (ActivityManager)mAppContextImpl.getSystemService(Context.ACTIVITY_SERVICE);
  2. List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
  3. if (list.size() != 0) {
  4. RunningAppProcessInfo topRunningProcess = list.get(0);
  5. if(topRunningProcess.processName.equals("com.android.xx.xxxxx")){
  6. return true;
  7. }
  8. }
  9. return false;

解决如何监听Activity切换的更多相关文章

  1. 解决怎样监听Activity切换

    本篇博文在我之前的博文中已经提到了,可是监听Activity切换又能够作为一个单独的内容来叙述,因此这里又单独拿了出来进行赘述. Activity的切换无非有两种.第一种:启动或者创建一个新的Acti ...

  2. ImageView 会盖掉ScrollView的OnTouchListener,监听Activity的手势

    当Activity的高度不够滑动的时候,ImageView会盖掉ScrollView的OnTouchListener监听. 这个时候须要设置Activity的(或者想直接监听Activity的手势也能 ...

  3. Android - 监听Activity点击无效

    监听Activity点击无效 本文地址: http://blog.csdn.net/caroline_wendy Activity须要先在Manifest注冊,才干在app中使用; Manifest: ...

  4. (原)android中的动画(三)之动画监听&页面切换动画

    1.动画也可以设置监听事件,例如在动画结束时需要执行某操作 把要执行的代码写在onAnimationEnd()回调方法中即可: anim.setAnimationListener(new Animat ...

  5. 解决Oracle监听错误的一种办法

    1:事出有因 安装oracle数据库,默认安装的是orcl数据库,安装完成后查看了一下字符集是gbk的,由于业务需要al32utf8的字符集,所以需要修改字符集,但是修改却无效.于是就删除了默认的or ...

  6. laydate 监听日期切换

    ```` //日期范围 laydate.render({ elem: '#Time', range: "至", max: gitData() ,done: function(val ...

  7. app进入后台之后接收到通知,点进去进入新的页面,再次进入后台,再点击通知进入页面(,两次通过通知进入的页面,创建了两次,会多一个页面,)解决办法监听

    在点击通知进入的页面的 //UIApplicationWillResignActiveNotification是app即将进入后台的方法 //增加监听使它在进入后台之前pop上一个页面 - (void ...

  8. 解决visualsvn监听ip 错误的问题

    系统重启+休眠之类的,弄几次,莫名其妙的svn就连接不上了, 有时候启动不起,有时候是启动连接不上,发现监听的ip错了 TCP    [::]:443               [::]:0     ...

  9. sencha touch 监听视图切换动画(animation)

    var animation = this.getLayout().getAnimation(); //添加监听 animation.on({ scope: this, animationend: 'o ...

随机推荐

  1. 【20160924】GOCVHelper 图像处理部分(3)

    //根据轮廓的圆的特性进行选择     vector<VP> selectShapeCircularity(Mat src,Mat& draw,vector<VP> c ...

  2. javascript 设计模式1----单例模式

    定义:保证一个类仅有一个实例,并提供一个访问的全局接口: 就是收:当我们 var a = new a(); var a1 = new a()是:a与a1是相等的.怎么实现呢,就是第一次实例化.第二不在 ...

  3. Checkpoint--与lazy writer区别

    checkpoint目的是减少数据库的恢复时间(服务奔溃或重启服务后的恢复),而lazy writer的目的是保证SQL OS 有空闲缓存块和系统有一定可用内存. Checkpoint和lazyWri ...

  4. Displaying Window In Center In Oracle Forms 6i

    Center window automatically  in Oracle Forms 6i, use the following procedure by passing window name ...

  5. How To Use DBLink In Oracle Forms 6i

    You want to connect multiple databases in oracle forms to perform certain tasks, for example you nee ...

  6. 微信小程序注册页面

    Page Page() 函数用来注册一个页面.接受一个 object 参数,其指定页面的初始数据.生命周期函数.事件处理函数等. object 参数说明: 属性 类型 描述 data Object 页 ...

  7. mysql 增删改查基本语句

    增: insert insert into 表名(字段1,字段2,字段3......字段N) values(值1,值2,值3): 如果不申明插入那些字段,则默认所有字段. 在插入时注意,往哪个表增加, ...

  8. [转] 浅谈Linux系统的启动流程

    原文:http://blog.csdn.net/justdb/article/details/9621271 版权声明:本文为博主原创文章. Linux系统的启动时通过读取不同的配置文件,执行相应的S ...

  9. TextView 行数控制

    控制textview只显示 2 行文本,超过 2 行显示展开/折叠按钮(mShowImage),isShow=true时,是展开状态,isShow=false时,是折叠状态 方法一: int line ...

  10. Shell 变量

    定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_name="runoob.com" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一 ...