解决如何监听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 ...
随机推荐
- EF获取一个或者多个字段
有时候直接查询出一个实体,比较浪费性能,对于字段比较少的表来说差异不大,但是如果一个表有几十个字段,你只要取出一个字段或者几个字段,而取出整个实体,性能就会有差异了. /// <summary& ...
- 一步一步教你编写与搭建自动化测试框架——python篇
[本文出自天外归云的博客园] 这两天用python写了一个自动化测试框架,取名为Auty.准备用来做Web方面的接口测试,以下为Auty框架一步一步的搭建过程——
- 【前端】String.prototype.match() 用法详解
var str="1 plus 2 equal 3" // 正则表达式 console.log(str.match(/\d+/g)); // ["1", &qu ...
- Spring MVC 线程安全问题的思考
Spring MVC 线程安全问题的思考 在读一些博文的时候发现有些文章对SpringMVC的Controller线程安全的验证并不正确,比如没有探究controller线程不安全的具体原因,比如将请 ...
- DAO
DAO Data Access Object DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道. 夹在业务逻辑与数据库资源中间. DAO模式是标准 ...
- GZFramework代码生成器插件使用教程
代码生成器分两种 1.基于独立exe生成程序 直接运行软件目录下GZFrameworkCodeGenerate.exe文件即可 2.基于VS插件生成 目录中分为两部分:全局缓存和VS插件 1.添加全局 ...
- c# base关键的理解
base 最大的使用地方在面相对性开发的多态性上.(什么是多态,如何理解多态) base可以[完成]创建派生类实例时调用其基类构造函数或者调用基类上已经被其他方法重写的方法 //关于base调用基类构 ...
- iOS核心动画学习整理
最近利用业余时间终于把iOS核心动画高级技巧(https://zsisme.gitbooks.io/ios-/content/chapter1/the-layer-tree.html)看完,对应其中一 ...
- mysql sql常用语句大全
SQL执行一次INSERT INTO查询,插入多行记录 insert into test.person(number,name,birthday) values(5,'cxx5',now()),(6, ...
- APP链接请求电话
1.使用OpenURL执行:[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:07551111&qu ...