您的位置:首页 > 移动开发 > Android开发

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

2013-11-19 16:11 483 查看
两周的奋战,终于对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

[java]
view plaincopyprint?

public StateManager(AbstractGalleryActivity activity) {
mActivity = activity;
}

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

1. startState()——startActivity()

[java]
view plaincopyprint?

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()中作了什么

}

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

[java]
view plaincopyprint?

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();
}

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

[java]
view plaincopyprint?

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

}
}

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


4.resume

[java]
view plaincopyprint?

public void resume() {
if (mIsResumed) return;
mIsResumed = true;
if (!mStack.isEmpty()) getTopState().resume();
}

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

5.pause——stop

[java]
view plaincopyprint?

<SPAN style="FONT-SIZE: 12px">public void pause() { if (!mIsResumed) return; mIsResumed = false; if (!mStack.isEmpty()) getTopState().onPause(); }</SPAN>

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

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

下一篇关注从一个ActivityState对象到另一个ActivityState的跳转。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: