解决如何监听Activity切换

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

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

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

[java] view
plain
copyprint?

  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

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

实现方式如下:

[java] view
plain
copyprint?

  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;
时间: 2024-10-23 09:43:27

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

解决怎样监听Activity切换

本篇博文在我之前的博文中已经提到了,可是监听Activity切换又能够作为一个单独的内容来叙述,因此这里又单独拿了出来进行赘述. Activity的切换无非有两种.第一种:启动或者创建一个新的Activity:另外一种:唤醒后台执行的Activity. 因此假设我们可以成功监听到启动或者创建一个Activity,或者唤醒Activity我们就基本完毕了Activity的切换的监听. 在源代码/frameworks/base/core/java/android/app文件夹下ActivityThr

Android - 监听Activity点击无效

监听Activity点击无效 本文地址: http://blog.csdn.net/caroline_wendy Activity须要先在Manifest注冊,才干在app中使用; Manifest: <activity android:name="me.chunyu.tvdoctor.healthvideo.VideoPlayingActivity" android:label="@string/app_name" /> 在内部库的G7Anno中: @

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

当Activity的高度不够滑动的时候,ImageView会盖掉ScrollView的OnTouchListener监听. 这个时候需要设置Activity的(或者想直接监听Activity的手势也可以这样设置) @Override public boolean dispatchTouchEvent(MotionEvent ev){ super.dispatchTouchEvent(ev); return productGestureDetector.onTouchEvent(ev); } Im

解决网络监听多次发送广播的问题

有时候我们需要写一个程序来监听网络的变化,以实现即时刷新的问题,比如微信或者QQ都有自动重连的功能.单纯的用广播接收和ConnectivityManager难以实现,因为每次我们切换g网和wifi或者启用一个网络,系统都会发送多次网络变化的广播,如果我们把业务逻辑放在广播接收器里面处理,就会不必要的调用多次.比如当我们启动wifi时,系统将发送多次广播,当我们判断是否有网络连接的时候,会多次判断有网络(如果刚刚启动数据流量或者wifi).这样里面的代码就会重复执行.想了各种办法,最终想到的解决方

【hugo】- hugo 监听浏览器切换title

hugo 博客 监听浏览器title 动态改变浏览器title标题 找到head.html themes/maupassant/layouts/partials/head.html 添加监听js 可以从html中发现,分为home页面和其他页面,两种展示的不同,所以需要改这两部分 {{ if .IsHome -}} <title>{{ .Site.Title }} | {{ .Site.Params.subtitle}}</title> <meta property=&quo

如何解决OnTouch监听事件只监听到DOWN操作,没有监听到MOVE和UP操作

解决方法其实很简单,只需要 把return false改成return true即可.

jquery 解决事件监听动画延迟触发的问题

上代码 <div id="small"></div> <div id="large"></div> #small{ width: 100px; height: 100px; background: red; position: absolute; top: 100px; left: 100px; } #large{ width: 200px; height: 200px; background: purple; pos

【Android】利用Activity生命周期监听应用前后台切换

~转载请注明:http://blog.csdn.net/u013015161/article/details/46762991 实现介绍 在Android应用开发中,我们有时候需要监听到应用前后台的切换.这里提供一种思路,该思路并非原创,而是一种比较通用的办法,这里做一下介绍,附带实际过程中遇到的问题的解决. 具体实现思路是通过重写Activity的onResume方法和onStop方法实现,即在onStop里判断应用是否切换到后台,在onResume里判断是否切换到前台. 先回顾一下Activ

android应用锁之监听应用前后台切换方式

今天在做技术总结,顺便就把知识共享,个人崇尚分享. 通过以下方式来监听是不是发生了应用的前后台切换: 1. android api 10 – 15 通过ActivityManager registerActivityWatcher方法注册IActivityWatcher的方式监听. 2. android api 16 – 20 通过监听/dev/log/events文件内容变化来监听应用切换变化. 为什么这个方式能成功监听: 因为/dev/log/events是内核的日志输出字符设备终端文件.