Android ActivityLifeCallbacks解析

peqa2188 8年前
   <p>今天利用下班的时间来整理一篇在实际遇到的一个新的知识点,对于我来说是新的。</p>    <p>文章的名字也是ActivityLifeCallbacks,意思为Activity的生命周期回调。实际上,并不是标题党那么吓人,就是android.app.Application里的一个接口,只是之前没有实际使用过,所以花了一个晚上的时间来整理这么一个blog,让自己加深记忆,同时也算总结一下它的基本用法。</p>    <p>那么,这篇的文章的主角,就是android.app.Application中的一个接口,名字就是ActivityLifecycleCallbacks,android的源码中并没有给出这个内部接口的文档(一点都没有),去官方API查也没有什么有用的信息,只是把接口中需要实现的方法罗列了出来,然后,就没有然后了。</p>    <p>既然这样,我们就从实际项目中出发。 ActivityLifecycleCallbacks是Application中的一个内部接口,public修饰的,那么就意味着一些类可以实现这个接口来完成个功能。 ActivityLifecycleCallbacks想简单可以简单,想复杂也可以复杂,就看我们需要完成什么功能。接下来,我们从这个接口的内部去看看,它都定义了哪些需要实现的功能。</p>    <p>Application. ActivityLifecycleCallbacks</p>    <pre>  <code class="language-java">public interface ActivityLifecycleCallbacks {</code></pre>    <pre>  <code class="language-java">// When activity is created, this method will be called.   void onActivityCreated(Activity activity, Bundle savedInstanceState);     // When onStart method runs, the method will be called.   void onActivityStarted(Activity activity);     // When onResume method runs, the method will be called.   void onActivityResumed(Activity activity);     // When onPause method runs, the method will be called.   void onActivityPaused(Activity activity);     // When onStopped method runs, the method will be called.   void onActivityStopped(Activity activity);     // When activity needs to save state with bundle, this method will be called.   void onActivitySaveInstanceState(Activity activity, Bundle outState);     // When onDestroy method runs, the method will be called.   void onActivityDestroyed(Activity activity);</code></pre>    <p>}</p>    <p>在上面的源码中,我给每一个方法标识出了注释,其实,不难发现, ActivityLifecycleCallbacks这个接口就是在描述一个Activity的生命周期,Activity的每一个生命周期都对应一个接口中的一个方法,同时,目标Activity从创建(onCreate)到销毁(onDestroy),每一个接口方法中都有Activity的实例作为参数传入,那么对应这个Activity实例,我们就可以做一些简单或者复杂的实现了。</p>    <p>学习新的内容,对于程序猿来说,一定要先学会使用,然后在去探究它的内部原理,由浅入深,这样体会更深,把握脉络更准确,有可能创造来更优秀的东西。</p>    <p>它的基本使用是很简单的:</p>    <ul>     <li>我们可以直接利用Application的子类来实现接口,也可以自己定义类来实现接口,那么我们就选择最简单的,直接利用Application的子类。</li>     <li>在MyApplication的onCreate方法中,注册这个接口。</li>     <li> <p>完成接口方法的具体实现。</p> <pre>  <code class="language-java">public class BaseApplication extends Application implements Application.ActivityLifecycleCallbacks {  @Override    public void onCreate() {</code></pre> <pre>  <code class="language-java">super.onCreate();    this.registerActivityLifecycleCallbacks(this);</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityCreated(Activity activity, Bundle savedInstanceState) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityCreated");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityStarted(Activity activity) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityStarted");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityResumed(Activity activity) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityResumed");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityPaused(Activity activity) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityPaused");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityStopped(Activity activity) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityStopped");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivitySaveInstanceState(Activity activity, Bundle outState) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivitySaveInstanceState");</code></pre> <p>}</p> <p>@Override</p> <p>public void onActivityDestroyed(Activity activity) {</p> <pre>  <code class="language-java">Log.i("BaseApplication", "onActivityDestroyed");</code></pre> <p>}</p> <p>}</p> </li>    </ul>    <p>在这个简单的实现里,我们只需要完成上面的三条就可以了,那ActivityLifecycleCallbacks就可以发挥作用了。我们的实现超级简单就是打印log,所以,log的打印顺序会跟着Activity的生命周期顺序来完成。</p>    <p>那么既然是这样,接下来就来分析整体的注册和执行流程。</p>    <pre>  <code class="language-java">public class Application extends ContextWrapper implements ComponentCallbacks2 {       private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<ActivityLifecycleCallbacks>();       ...</code></pre>    <pre>  <code class="language-java">// register method   public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {        synchronized (mActivityLifecycleCallbacks) {             mActivityLifecycleCallbacks.add(callback);        }   }     // unregister method   public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {        synchronized (mActivityLifecycleCallbacks) {             mActivityLifecycleCallbacks.remove(callback);        }   }     // 只举一个方法来说明,其它的大同小异   /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {           Object[] callbacks = collectActivityLifecycleCallbacks();           if (callbacks != null) {               for (int i=0; i<callbacks.length; i++) {                   ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,                           savedInstanceState);               }           }   }</code></pre>    <p>}</p>    <p>mActivityLifecycleCallbacks是一个数组列表,存放的就是 ActivityLifecycleCallbacks 的实现类,从上面的栗子来看,就是我们自定义的Application,注册和解除注册就是一个操作数组列表的动作,没有复杂的内容。</p>    <p>dispatchActivityCreated()方法就是对接口中的方法进行调用的,其实也没啥难的,原理很简单。</p>    <p>首先这个方法/ <em>package</em> /的,这里有点说道,一会我们再详细说明。方法传递了一个Activity作为参数,同时,传入了一个savedInstanceState的bundle参数,打眼一看,这就是Activity的onCreated方法的反向执行么。那么随便一猜就知道,这个方法肯定要再onCreate方法中调用的,方法内部执行也很简单, collectActivityLifecycleCallbacks 方法会收集到所有的 ActivityLifecycleCallbacks ,然后遍历,就直接完成回调了。对于回调方法的具体执行就是我们在MyApplication中给出的实现。很简单吧!</p>    <p>最后我们在去验证一下, dispatchActivityCreated 是如何调用的。既然是跟着Activity生命周期走的,肯定在Activity类中了。进去看一下。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f775adbba08c3d6877e0f730d913be12.png"></p>    <p>Paste_Image.png</p>    <p>以上就是在Activity类中的onCreate方法的截图,图中红色圈住的部分就是我们在找的调用了。</p>    <p>小结:</p>    <p>关于 ActivityLifecycleCallbacks的使用和原理是很简单的,基本上大致看看就知道原理和使用了。之所以写这个小短文,一是自己之前没使用过,二是既然是新东西就有必要学习并且记录一下。</p>    <p>关于如何使用它并且在什么场景下使用它,这里有话要说。如果我们有必要对每一个Activity的生命周期进行管控,那么 ActivityLifecycleCallbacks 就有存在的价值,我们在Activity的创建或者销毁等周期进行一些打点,记录或者收集页面信息的时候,这些场景下可能会有用武之地。</p>    <p>但是,Android系统是不建议我们这么做的。为啥这么说,几点来看吧。</p>    <p>这些方法是Inner—API同时是package范围内的。上图!</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ab3a589505583ebeb1ebb9abe6eb6691.png"></p>    <p>Paste_Image.png</p>    <p>图中圈住的两处就能说明问题了,首先,系统之所以没有给出明确doc或者说明,而是给了这么一个// Internal API,就是说这些方法是供Android framework内部使用的API,我们在platform下的android.jar下的字节码文件中是找不到这些方法的,因为它们被隐藏了,也就说这些API不准备对外提供使用,据我所查资料得知,@hide掉的API方法是无法对外提供的,而且在正常提供的android包下是找不到这些方法,只有真正在程序执行的时候,系统会在一个对应的framework.jar下完成隐藏API的内部调用,系统将它们分离开就是不希望这些内部API暴露出去。这也就是为什么我们在第一张图中,getApplication().dispatchActivityCreated()方法的时候,为什么这个方法是红色(找不到)的原因。因为它根部就不再android.jar中。</p>    <p>所以,如果不是必须,就尽量不去完成这个任务,了解了这个接口以及原理和使用就可以。如果真的有需要,也要尽量保证不要破坏Activity同时也要小心内存泄漏的问题。</p>    <p> </p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/f49f7bb44126</p>    <p> </p>