Android4.2.2 Gallery2源码分析(8)——假装的Activity

两周的奋战,终于对Gallery的结构有了个大致的了解。Gallery是一个很好的Android系统知识的学习源码,不仅仅因为它设计到了多线程,布局优化,Opengl的结合等等内容。还有两点必须说明的地方,一个是前文提到国的GLView.java:Gallery没有用到任何android提供的View类,而是自己写了一个融合Opengl绘图的GLView,掌握它对于理解android的View架构有很大的帮助。另外一个则是本文要提到的ActivityState.java。它也同GLView一样,模仿了系统Activity类的实现,Gallery中的页面不是一个个的Activity,而是一个个的ActivityState。同时还有一个StateManager.java类帮助管理这些ActivityState子类。


   初学Activity的时候,我们总是在onCreate()编写自己的代码,疑惑的是这个onCreate()由谁调用呢?深入学习之后,我们知道它由Android系统进程在合适的时候调用。Gallery中的StateManager很好的模仿了这一点,从这里我们可以窥见Activity的生命周期是如何通过这几个on...函数实现的。

StateManager.java

  1.  public StateManager(AbstractGalleryActivity activity) {  
  2.         mActivity = activity;  
  3.     }
    public StateManager(AbstractGalleryActivity activity) {
        mActivity = activity;
    }
这是它的构造函数,AbstractGalleryActivity是一个继承自系统Activity的类,因此最终Gallery里模仿的这些ActivityState类还是要和某个具体的Activity关联起来,因为系统只认识真正的Activity。

1. startState()——startActivity()

  1.  public void startState(Class<? extends ActivityState> klass,  
  2.             Bundle data) {  
  3.         Log.v(TAG, "startState " + klass);  
  4.         ActivityState state = null;  
  5.         try {  
  6.             state = klass.newInstance();  
  7.         } catch (Exception e) {  
  8.             throw new AssertionError(e);  
  9.         }  
  10.         if (!mStack.isEmpty()) {//栈不为空   
  11.             ActivityState top = getTopState();//获取栈顶ActivityState对象   
  12.             top.transitionOnNextPause(top.getClass(), klass,  
  13.                     StateTransitionAnimation.Transition.Incoming);  
  14.             if (mIsResumed) top.onPause();//调用这个startState或者说创建一个新的ActivityState有两种可能,一是第一次启动   
  15.                                           //Gallery,创建的是AlbumSetPage,二是在几个ActivityState的子类状态间的切换   
  16.                                           //即AlbumSetPage和AlbumPage,AlbumPage和PhotoPage间的切换。在第二种情况中   
  17.                                           //某一个ActivityState已经在栈顶,处于保留(onResume)状态,因此mIsResumed为true。   
  18.                                           //这里的疑问是既然它们处于onResume,那么只需要调用onResume()即可,为什么还要创建新的   
  19.                                           //对象呢   
  20.         }  
  21.         state.initialize(mActivity, data);  
  22.   
  23.         mStack.push(new StateEntry(data, state));//每一个新创的ActivityState都要入栈,   
  24.         state.onCreate(data, null);  
  25.         if (mIsResumed) state.resume();//同上疑问。解决这个疑问,需要看什么时候调用的startState()和resume()中作了什么   
  26.     }
    public void startState(Class<? extends ActivityState> klass,
            Bundle data) {
        Log.v(TAG, "startState " + klass);
        ActivityState state = null;
        try {
            state = klass.newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
        if (!mStack.isEmpty()) {//栈不为空
            ActivityState top = getTopState();//获取栈顶ActivityState对象
            top.transitionOnNextPause(top.getClass(), klass,
                    StateTransitionAnimation.Transition.Incoming);
            if (mIsResumed) top.onPause();//调用这个startState或者说创建一个新的ActivityState有两种可能,一是第一次启动
                                          //Gallery,创建的是AlbumSetPage,二是在几个ActivityState的子类状态间的切换
                                          //即AlbumSetPage和AlbumPage,AlbumPage和PhotoPage间的切换。在第二种情况中
                                          //某一个ActivityState已经在栈顶,处于保留(onResume)状态,因此mIsResumed为true。
                                          //这里的疑问是既然它们处于onResume,那么只需要调用onResume()即可,为什么还要创建新的
                                          //对象呢
        }
        state.initialize(mActivity, data);

        mStack.push(new StateEntry(data, state));//每一个新创的ActivityState都要入栈,
        state.onCreate(data, null);
        if (mIsResumed) state.resume();//同上疑问。解决这个疑问,需要看什么时候调用的startState()和resume()中作了什么
    }
通过反射机制获取某个ActivityState子类的实例,因此在这里管理创建我们需要的ActivityState的实例,并且StateManager管理着一个栈,这个栈保存着创建的ActivityState实例。这也同Activity有着相类似的效果。

栈中保存的是StateEntry这一内部类,它只有两个成员,一个ActivityState和一个Bundle。因此栈中保存着一个ActivityState对象和它相关的数据。

关于这里的top.transitionOnNextPause(),我们先来看看Gallery图片浏览的结构:

主界面(AlbumSetPage)————>某个相册(AlbumPage)————>单张照片(PhotoPage)

这个函数对AlbumPage和PhotoPage二者的相互界面转换设置了动画。

2.startStateForResult——startActivityForResult


  1. public void startStateForResult(Class<? extends ActivityState> klass,  
  2.             int requestCode, Bundle data) {  
  3.         Log.v(TAG, "startStateForResult " + klass + ", " + requestCode);  
  4.         ActivityState state = null;  
  5.         try {  
  6.             state = klass.newInstance();  
  7.         } catch (Exception e) {  
  8.             throw new AssertionError(e);  
  9.         }  
  10.         state.initialize(mActivity, data);  
  11.         state.mResult = new ActivityState.ResultEntry();//state.mResult隶属于新创的这个ActivityState   
  12.         state.mResult.requestCode = requestCode;  
  13.   
  14.         if (!mStack.isEmpty()) {//如果栈不为空,那么把新创的这个ActivityState的state.mResult结果返回给栈顶的对象,因为这个ActivityState由栈顶的那个对象启动,结果也是它要的。   
  15.             ActivityState as = getTopState();  
  16.             as.transitionOnNextPause(as.getClass(), klass,  
  17.                     StateTransitionAnimation.Transition.Incoming);  
  18.             as.mReceivedResults = state.mResult;  
  19.             if (mIsResumed) as.onPause();  
  20.         } else {  
  21.             mResult = state.mResult;//第一次创建,结果由自己保存。   
  22.         }  
  23.   
  24.         mStack.push(new StateEntry(data, state));  
  25.         state.onCreate(data, null);//这里是我们需要关注的,入栈在onCreate()之前,因此界面上的所有操作应该都是对应于栈顶的那个对象。   
  26.         if (mIsResumed) state.resume();  
  27.     }
    public void startStateForResult(Class<? extends ActivityState> klass,
            int requestCode, Bundle data) {
        Log.v(TAG, "startStateForResult " + klass + ", " + requestCode);
        ActivityState state = null;
        try {
            state = klass.newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
        state.initialize(mActivity, data);
        state.mResult = new ActivityState.ResultEntry();//state.mResult隶属于新创的这个ActivityState
        state.mResult.requestCode = requestCode;

        if (!mStack.isEmpty()) {//如果栈不为空,那么把新创的这个ActivityState的state.mResult结果返回给栈顶的对象,因为这个ActivityState由栈顶的那个对象启动,结果也是它要的。
            ActivityState as = getTopState();
            as.transitionOnNextPause(as.getClass(), klass,
                    StateTransitionAnimation.Transition.Incoming);
            as.mReceivedResults = state.mResult;
            if (mIsResumed) as.onPause();
        } else {
            mResult = state.mResult;//第一次创建,结果由自己保存。
        }

        mStack.push(new StateEntry(data, state));
        state.onCreate(data, null);//这里是我们需要关注的,入栈在onCreate()之前,因此界面上的所有操作应该都是对应于栈顶的那个对象。
        if (mIsResumed) state.resume();
    }

3.createOptionsMenu

  1. public boolean createOptionsMenu(Menu menu) {  
  2.         if (mStack.isEmpty()) {  
  3.             return false;  
  4.         } else {  
  5.             return getTopState().onCreateActionBar(menu);//因为startState()调用在前,也即入栈在前。因此后续操作都是对应于当前栈顶的这个对象的。   
  6.         }  
  7.     }
    public boolean createOptionsMenu(Menu menu) {
        if (mStack.isEmpty()) {
            return false;
        } else {
            return getTopState().onCreateActionBar(menu);//因为startState()调用在前,也即入栈在前。因此后续操作都是对应于当前栈顶的这个对象的。
        }
    }

4.resume

  1.  public void resume() {  
  2.         if (mIsResumed) return;  
  3.         mIsResumed = true;  
  4.         if (!mStack.isEmpty()) getTopState().resume();  
  5.     }
    public void resume() {
        if (mIsResumed) return;
        mIsResumed = true;
        if (!mStack.isEmpty()) getTopState().resume();
    }
标志位调整为true,具体工作仍交付栈顶对象完成。

5.pause——stop

  1. <SPAN style="FONT-SIZE: 12px">    public void pause() {  
  2.         if (!mIsResumed) return;  
  3.         mIsResumed = false;  
  4.         if (!mStack.isEmpty()) getTopState().onPause();  
  5.     }</SPAN>  
    public void pause() {
        if (!mIsResumed) return;
        mIsResumed = false;
        if (!mStack.isEmpty()) getTopState().onPause();
    }
标志位mIsResumed的意义在于判断栈顶的这个ActivityState对象是处于暂停还是工作状态。这样理论上可以解释前面的疑问,当mIsResumed为true时,栈顶的对象当然应该暂停,让新建的对象工作。具体解释还需结合了ActivityState中各项on函数具体做了什么之后说明。

对于这部分内容,如同Activity一样,我们关注其生命循环,此处只写出部分内容,其他异曲同工,写出所有内容太过耗时,因此只在此处抛砖引玉写出开头。

下一篇关注从一个ActivityState对象到另一个ActivityState的跳转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值