解决怎样监听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 ...
随机推荐
- spring中MessageSource的配置使用方法3--ResourceBundleMessageSource
ApplicationContext接口扩展了MessageSource接口,因而提供了消息处理的功能(i18n或者国际化).与HierarchicalMessageSource一起使用,它还能够处理 ...
- APUE 学习笔记(九) 高级I/O
1. 非阻塞I/O 低速系统调用时可能会使进程永远阻塞的一类系统调用,包括以下调用: (1)某些文件类型你(网络socket套接字.终端设备.管道)暂无可使用数据,则读操作可能会使调用者永远阻塞 (2 ...
- 【CF676D】Theseus and labyrinth(BFS,最短路)
题意:给定一张N*M的地图,每一格都是一个房间,房间之间有门.每个房间可能有四个门,例如>代表右边只有一个门在右边即只能向右走,L代表左边没有门只能除了左其他都可以走等等.现在给出起点和终点,每 ...
- C/C++ XMPP/Jabber 客户端类库对比/点评 (转)
原文转自 http://blog.csdn.net/educast/article/details/31359835 1.gloox Ans. 老牌库,推荐 gloox是一个稳定功能完整的XMPP客户 ...
- 转 PV操作简单理解
传送门 PV操作简单理解 进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下: 进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作 ...
- 35深入理解C指针之---结构体基础
一.结构体基础 1.定义:结构体大大加强了C的数据聚合能力,可以使得不同类型的数据进行结合 2.特征: 1).结构体可以使得不同类型的数据进行结合 2).结构体可以使用内置的数据类型,包括指针 3). ...
- linux .so .a .o 文件
linux下文件的类型是不依赖于其后缀名的,但一般来讲:.o,是目标文件,相当于windows中的.obj文件.so 为共享库,是shared object,用于动态连接的,和dll差不多.a为静态库 ...
- 捕获错误并发邮件 register_shutdown_function
/** * 脚本程序异常捕获 */ function handleError() { global $config; $error = error_get_last(); if (isset($err ...
- window10下用ZIP压缩包安装 mysql 8.0.11
1.下载地址 https://dev.mysql.com/downloads/mysql/ 2.解压后的文件目录如图,复制到指定的文件目录,如我的 E:\root\mysql-8.0.11-winx6 ...
- luogu P1879 [USACO06NOV]玉米田Corn Fields
题目描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ...