打点利器——ActivityLifecycleCallbacks
来源:互联网 发布:沈阳贵德软件电话 编辑:程序博客网 时间:2024/06/01 09:51
1.什么是ActivityLifecycleCallbacks?他有什么用?
ActivityLifecycleCallbacks是一个定义在Application类中的接口,API level 14。这个接口可以监控App进程中所有的Activity,在生命周期收到回调。Application提供了注册和反注册接口:
void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
void unregisterActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
代码样例:
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } });
可以看到里面实现了Activity所有的生命周期。虽然Android中一般不需要集中式管理Activity,但这个接口仍然为那些需要所有Activity都实现的业务逻辑,在自己实现一个Activity子类作为App中所有Activity的基类这样的方案之外,提供了另外一种选择。而根据减低代码耦合度的准则,在同样能满足需求的前提下,这样的方案比增加Activity继承关系更好,更轻量级。
譬如页面打点这样的需求,就可以使用ActivityLifecycleCallbacks实现。
2.框架层是怎么实现的?
在Activity找一个回调,譬如onResume:
protected void onResume() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this); getApplication().dispatchActivityResumed(this); mActivityTransitionState.onResume(); mCalled = true; }
看到getApplication().dispatchActivityResumed(this);
接着看Application:
/* package */ void dispatchActivityResumed(Activity activity) { Object[] callbacks = collectActivityLifecycleCallbacks(); if (callbacks != null) { for (int i=0; i<callbacks.length; i++) { ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity); } } }
在自己的回调对象集合中执行所有回调对象的回调方法。
private Object[] collectActivityLifecycleCallbacks() { Object[] callbacks = null; synchronized (mActivityLifecycleCallbacks) { if (mActivityLifecycleCallbacks.size() > 0) { callbacks = mActivityLifecycleCallbacks.toArray(); } } return callbacks; }
collectActivityLifecycleCallbacks()通过线程安全的方法取到当前的回调对象集合。mActivityLifecycleCallbacks是一个ArrayList:
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<ActivityLifecycleCallbacks>();
所以,实际上collectActivityLifecycleCallbacks()返回的方法是通过toArray()得到的一个副本:
/** * Returns a new array containing all elements contained in this * {@code ArrayList}. * * @return an array of the elements from this {@code ArrayList} */ @Override public Object[] toArray() { int s = size; Object[] result = new Object[s]; System.arraycopy(array, 0, result, 0, s); return result; }
当然,通过System.arraycopy()得到的数组,里面的对象引用是相同的,对象并没有被拷贝,并非深拷贝。
再看注册和反注册方法:
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { synchronized (mActivityLifecycleCallbacks) { mActivityLifecycleCallbacks.add(callback); } } public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { synchronized (mActivityLifecycleCallbacks) { mActivityLifecycleCallbacks.remove(callback); } }
结合起来看,就是注册/反注册回调对象集合、获取当前回调对象集合这些操作在原始数据集mActivityLifecycleCallbacks上面被同一把锁保护,获取当前回调对象集合是原始数据集的一个副本(对象成员相同,并非副本),用他来脱离锁区域并处理回调。同时,因为已经释放锁,且并非在原始数据集上操作,所以不影响此时再有注册/反注册动作。
因为这个回调分发方法是Activity在自身的回调中同步调用的,所以在主线程执行。
3.有没有默认的回调对象?
由于Application没有给出接口直接访问已注册回调对象集合,所以用反射测一下:
package com.example.mi.myapplication;import android.app.Activity;import android.app.Application;import android.os.Bundle;import android.util.Log;import java.lang.reflect.Field;import java.util.ArrayList;public class MyApplication extends Application { public void testActCBs() { Class app = Application.class; try { Field field = app.getDeclaredField("mActivityLifecycleCallbacks"); field.setAccessible(true); Log.i("MyApplication", "callbacks - " + ((ArrayList<ActivityLifecycleCallbacks>) field.get(this)).size()); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} @Override public void onActivityStarted(Activity activity) {} @Override public void onActivityResumed(Activity activity) {} @Override public void onActivityPaused(Activity activity) {} @Override public void onActivityStopped(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} @Override public void onActivityDestroyed(Activity activity) {} }); Log.i("MyApplication", "callbacks - " + ((ArrayList<ActivityLifecycleCallbacks>) field.get(this)).size()); } catch (IllegalAccessException e) { Log.i("MyApplication", e.getMessage()); } catch (NoSuchFieldException e) { Log.i("MyApplication", e.getMessage()); } }}
在Activity中调用:
package com.example.mi.myapplication;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ((MyApplication)getApplication()).testActCBs(); }}
Log显示:
06-10 14:08:59.545 20696 20696 I MyApplication: callbacks - 006-10 14:08:59.545 20696 20696 I MyApplication: callbacks - 1
可见,框架层并无默认回调逻辑,这是一个完全给App的机制。
- 打点利器——ActivityLifecycleCallbacks
- ActivityLifecycleCallbacks——追踪Activity生命周期
- ActivityLifecycleCallbacks
- ActivityLifecycleCallbacks
- ActivityLifecycleCallbacks
- ActivityLifecycleCallbacks
- Application中的管理所有activity的利器:ActivityLifecycleCallbacks
- 自定义View——可打点记录的进度条
- Android开发——使用ActivityLifecycleCallbacks监控App是否处于后台
- Android进阶——借助简单便捷的ActivityLifecycleCallbacks实现全周期监听Activity
- 图像识别(7)——静态图片识别LED灯+Canny阈值调节+圆心打点
- 图像识别(10)——UVC预览+曝光滑动调节+Canny阈值调节+圆心打点
- Android activitylifecyclecallbacks
- Activitylifecyclecallbacks使用
- 详解ActivityLifecycleCallbacks
- JUnit——单元测试利器
- vim——编辑利器
- 单元测试利器——Mockito
- Spark2.0.X源码深度剖析之 Spark Submit..
- 实例探索Java模式之路——适配器模式
- C语言之typedef详解
- Lintcode68 Binary Tree Postorder Traversal solution 题解
- Java:HttpUtils :发送get/post请求
- 打点利器——ActivityLifecycleCallbacks
- 疯狂的bLue(dp)
- 存储的瓶颈终篇(8)
- 西开js 6.3/6.4
- OkHttp基本使用
- 前端进阶——作用域的相关知识
- Qt4.8.6+VS2010安装配置教程
- BZOJ 2287: 【POJ Challenge】消失之物 背包dp
- 19个必须知道的Visual Studio快捷键