浙江大洋建设集团有限公司网站,运营托管公司,wordpress国内案例,云计算网站建设Activity生命周期监听
使用 Instrumentation 对 Activity 生命周期进行监听。 优点#xff1a;
全局仅一次反射#xff0c;性能影响极小所有Activity的生命周期都能够被监听到由于Java的单继承#xff0c;为了拓展性#xff0c;可以使用装饰器模式对Instrumentation进行功…Activity生命周期监听
使用 Instrumentation 对 Activity 生命周期进行监听。 优点
全局仅一次反射性能影响极小所有Activity的生命周期都能够被监听到由于Java的单继承为了拓展性可以使用装饰器模式对Instrumentation进行功能加强但个人觉得这样做不推荐
缺点
只使用于Activity的生命周期监听FragmentManger实例的应用关系复杂不容易反射替代应该可以实现或者用其他方式Hook
1. 实现原理
回顾到 Activity 的启动流程AMS 向 APP 进程发来 Activity 启动请求ApplicaitonThread 作为binder线程的维护者收到消息将消息回调到 ActivityThread 的Handler.handleMessage()启动Activity。核心为performLaunchActivity()-Instrumentation.callActivityOnCreate()-activity.performCreate() 类似的还有
//Instrumentation.java
pubilc void callActivityOnCreate(Activity activity,Bundle budle,PsersistableBundle p){
//...
}
public void callActivityOnCreate(Activity activity,Bundle
bundle){
//...
}
public void callActivityOnStart(Activity activity){
//...
}
//...OnPause、OnStop、OnDestroy也都类似
这些方法都是开放的所有Activity的生命周期都会经过它而且这些方法都明确了要调用哪个Activity的生命周期。这就给了我们一个机会来监听 Activity。同时这个设计也表现了 Android 的事件驱动设计。
2. 实现方法
我们可以通过继承一个 Instrumentation 来给这些方法加个钩子注意一定要回调父类的本方法否则就破坏程序了 public class FyInstrumentation extends Instrumentation {public static final String TAG FyInstrumentation;//------------ onCreate ------------Overridepublic void callActivityOnCreate(Activity activity, Bundle bundle) {Log.e(TAG, begin onCreate: activity);super.callActivityOnCreate(activity, bundle);Log.e(TAG, end onCreate activity);}Overridepublic void callActivityOnCreate(Activity activity, Bundle bundle, PersistableBundle persistentState) {Log.e(TAG, begin onCreate: activity);super.callActivityOnCreate(activity, bundle,persistentState);Log.e(TAG, end onCreate activity);}//-------------- onStart ---------------Overridepublic void callActivityOnStart(Activity activity){Log.e(TAG, begin onStart: activity);super.callActivityOnStart(activity);Log.e(TAG, end onStart activity);}//-------------- onResume ---------------Overridepublic void callActivityOnResume(Activity activity){Log.e(TAG, begin onResume: activity);super.callActivityOnResume(activity);Log.e(TAG, end onResume activity);}//-------------- onPause ---------------Overridepublic void callActivityOnPause(Activity activity){Log.e(TAG, begin onPause: activity);super.callActivityOnPause(activity);Log.e(TAG, end onPause activity);}//-------------- onStop ---------------Overridepublic void callActivityOnStop(Activity activity){Log.e(TAG, begin onStop: activity);super.callActivityOnStop(activity);Log.e(TAG, end onStop activity);}//-------------- onDestroy ---------------Overridepublic void callActivityOnDestroy(Activity activity){Log.e(TAG, begin onDestroy: activity);super.callActivityOnResume(activity);Log.e(TAG, end onDestroy activity);}}
把我们的 FyInstrumentation 替换掉原有的 Instrumentation。 何时替换都可以只需要在我们目标监听的 Activity 开始之前就替换好即可。所以我这里就把它放在 MyApplication 中在所有 Activity 开始之前就替换好。 先写一个工具类由于单例设计ActivityThread实例的获取我们可以通过静态方法currentActivityThread()来获取。再对它的成员变量 mInstrumentation 进行反射替换成我们的 Instrumentation。
public class HookHelper {public static final String TAG HookHelper;public static void attachContext() throws Exception{//获取到当前的activityThreadClass? atClazz Class.forName(android.app.ActivityThread);Method method atClazz.getMethod(currentActivityThread);Object at method.invoke(null);Log.e(TAG,at.getClass().getName() );Field f at.getClass().getDeclaredField(mInstrumentation);f.setAccessible(true);f.set(at,new FyInstrumentation());}
}
最后我们在MyApplication中进行替换 public class MyApplication extends Application {Overridepublic void onCreate() {super.onCreate();try {HookHelper.attachContext();} catch (Exception e) {e.printStackTrace();}}
}3.测试监听
进入到 MainActivity然后点击按钮跳转到TestFragmentActivity
2023-02-20 15:48:37.280 3737-3737/com.company.rxjavastudy E/FyInstrumentation: begin onCreate: com.company.lifecycle2.MainActivityd3e13d
2023-02-20 15:48:37.700 3737-3737/com.company.rxjavastudy E/FyInstrumentation: end onCreatecom.company.lifecycle2.MainActivityd3e13d
2023-02-20 15:48:37.703 3737-3737/com.company.rxjavastudy E/FyInstrumentation: begin onStart:
...
2023-02-20 15:52:39.380 3737-3737/com.company.rxjavastudy E/FyInstrumentation: end onStopcom.company.lifecycle2.MainActivityd3e13d内容太多了我把顺序梳理如下APP开启后进入到活动A点击按钮跳转到活动B
A-onCreate
A-onStart
A-onResume
A-onPause
B-onCreate
B-onStart
B-onResume
A-onStop测试完成监听成功。 对生命周期的细节大家可以复习关于Activity的四大启动模式与Activity跳转的生命周期的关系也注意一下 onNewIntent()这是在复用Activity的时候调用的。