Android平台Gallery2应用分析(三)---StateManager和AbstractGalleryActivity

StateManager

StateManager中有个Stack<StateEntry> mStack,类似于ActivityManager中的ActivityStack。用于控制相册界面的窗口堆栈管理,成员为StateEntry类。再看startState这个函数:

    public void startState(Class<? extends ActivityState> klass,
            Bundle data) {
        Log.v(TAG, "startState " + klass);
        ActivityState state = null;
        try {
            // 用窗口类创建一个ActivityState实例
            state = klass.newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
        // 堆栈非空
        if (!mStack.isEmpty()) {
             // 获取栈顶ActivityState
            ActivityState top = getTopState();
            top.transitionOnNextPause(top.getClass(), klass,
                    StateTransitionAnimation.Transition.Incoming);
            // 调用栈顶ActivityState的onPause
            if (mIsResumed) top.onPause();
        }
        // 初始化当前的ActivityState,这个和startActivity非常相似
        state.initialize(mActivity, data);
        // 初始化后入栈
        mStack.push(new StateEntry(data, state));

        Log.d(TAG, "startState: startState->onCreate");
        // 调用新ActivityState实例的onCreate,这个和startActivity的流程又好相似
        state.onCreate(data, null);
        Log.d(TAG, "startState: startState->resume");
        // 调用新ActivityState实例的onResume
        if (mIsResumed) state.resume();
}
可以说这个函数和启动应用activity的流程非常相似,只是简化了流程而已。另外,startStateForResult也和startActivityForResult类似。

AbstractGalleryActivity
在介绍AlbumSetPage、AlbumPage、PhotoPage等页面前,必须先介绍AbstractGalleryActivity,因为以上三个页面的父类ActivityState中有成员变量AbstractGalleryActivity mActivity。相册的Activity实际上只有一个,可以说就是这个mActivity,通过StateManager和DataManager来控制显示不同的页面。
继承自Activity,其中有几个重要成员:GLRootView mGLRootView,StateManager mStateManager,DataManager,GalleryActionBar mActionBar,OrientationManager mOrientationManager。
其中GalleryActionBar就是相册各个界面顶部的ActionBar控件。按照Activity的生命周期,在onCreate中创建OrientationManager对象赋予mOrientationManager,调用toggleStatusBarByOrientation在屏幕横竖屏时对window的全屏标记做增加和清除。

    // Shows status bar in portrait view, hide in landscape view
    private void toggleStatusBarByOrientation() {
        if (mDisableToggleStatusBar) return;

        Window win = getWindow();
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        } else {
            win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }
在setContentView()中加载GLRootView。在onStart()中注册AlertDialog的onClick处理。在onResume(),onPause()中都会分别对StateManager,DataManager做对应的onResume, onPause操作。例如:

    @Override
    protected void onResume() {
        super.onResume();
        mGLRootView.lockRenderThread();
        try {
            getStateManager().resume();
            getDataManager().resume();
        } finally {
            mGLRootView.unlockRenderThread();
        }
        mGLRootView.onResume();
        mOrientationManager.resume();
    }
其中 mGLRootView会调用 lockRenderThread(),在执行完xxx.resume()后会再调用unlockRenderThread()。下面是GLRootView的lockXXX()和unlockXXX()函数。

    @Override
    public void lockRenderThread() {
        mRenderLock.lock();
    }

    @Override
    public void unlockRenderThread() {
        mRenderLock.unlock();
    }
其中 mRenderLock是ReentrantLock对象。那么ReentrantLock(可重入锁)的作用是什么?
因为Gallery的每个页面AlbumSet、AlbumPage、PhotoPage、PhotoView都是同一个Activity,界面的控制是通过StateManager以及DataManager,切换进入每个状态页面,都会获取不同的GLRootView,所以必须保证GLRootView是锁定情况下,才能对StateManager以及DataManager做处理。

欢迎转载和技术交流,转载请帮忙注明出处,http://blog.csdn.net/discovery_by_joseph谢谢!

你可能感兴趣的:(android,应用,多媒体,相册,Gallery2)