解决如何监听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 ...
随机推荐
- Visual Studio 2015简体中文企业版/专业版下载+有效激活密钥
Visual Studio 2015是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具.集成开发环境(IDE)等等.所写的目标代码适用于微软支持的所有 ...
- WF4.0入门(一)
WF的全称是Windows Workflow Foundation .这是 Microsoft 快速构建基于工作流的应用程序的编程模型.引擎和工具.NET Framework 4 中这个 WF 版本更 ...
- maven+Jenkins学习小记
jenkins配置方法1,tomcat下载,解压,切换到bin目录,配置环境变量,地址为catalina.bat文件夹下,也就是bin目录,再配置path变量2,启动tomcat,dos命令,cata ...
- GMF中,删除节点和连线的另一种实现
问题 在GMF中,如果需要programmatically删除节点或连线,在google中我们很容易搜索到<GMF中,删除节点和连线的实现>一文(我并不确定这是原创作者的原始链接),很多人 ...
- 关于Youtube URL的十个技巧
你一定很熟悉Youtube了,知道它是一个视频分享网站.是的,youtube目前十分流行,你也许会常常访问.这里有一些关于youtube url的技巧,了解了这些技巧,你就可以更好的利用youtube ...
- php中session机制的详解
[补充]session_start()要放在php最前面,header()函数也要放在session_start()之后. [读了下面的文章转载的文章后自己的理解]: 1,通过phpinfo()函数可 ...
- javascript Array Methods(学习笔记)
ECMAScript 5 定义了9个新的数组方法,分别为: 1.forEach(); 2.map(); 3.filter(); 4.every(); 5.some(); 6.reduce() ...
- python成长之路【第四篇】:装饰器
实现装饰器的知识储备: 示例: def f1(): print("f1") 1.函数即“变量” #上面的示例中,函数f1为变量,它指向内存地址.而f1()表示函数执行. 2.高阶函 ...
- Android 利用xUtils框架实现对sqllite的增删改查
首先下载xUtils,下载地址:https://github.com/wyouflf/xUtils 把下载好的文件压缩,把里面的jar包拷进项目中如图所示: 这里新建一个User类进行测试增删改查 ...
- IntelliJ IDEA的快捷键
本人整理了一部分,如果有无效的,欢迎指出.