首页 > 代码库 > 图库Gallery3D(Gallery2)分析(四) 菜单命令执行过程分析
图库Gallery3D(Gallery2)分析(四) 菜单命令执行过程分析
该分析基于 Android4.2的Gallery2
1 菜单创建过程分析。
Gallery的父类是AbstractGalleryActivity类,AbstractGalleryActivity的父类是Activity类。所以菜单创建是调用的AbstractGalleryActivity的菜单创建函数。
public class AbstractGalleryActivity extends Activity implements GalleryContext { private static final String TAG = "AbstractGalleryActivity"; private StateManager mStateManager; @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); return getStateManager().createOptionsMenu(menu); } }
每一个子页面(比如PhotoPage)都是ActivityState的子类。StateManager是一个子页面(ActivityState)管理类,负责子页面切换,命令执行,界面刷新等职能。Gallery将所有操作命令交给StateManager执行,StateManager再将命令分发给当前子页面执行。
public class StateManager { private static final String TAG = "StateManager"; private AbstractGalleryActivity mActivity; private Stack<StateEntry> mStack = new Stack<StateEntry>(); public boolean createOptionsMenu(Menu menu) { if (mStack.isEmpty()) { return false; } else { return getTopState().onCreateActionBar(menu); } } public ActivityState getTopState() { Utils.assertTrue(!mStack.isEmpty()); return mStack.peek().activityState; } }
StateManager将创建菜单操作,分发给当前子页面(以PhotoPage为例)执行。子页面根据页面属性配置并更新一下MenuExecutor。这样就完成了菜单的创建工作。
public class PhotoPage extends ActivityState{ private static final String TAG = "PhotoPage"; @Override protected boolean onCreateActionBar(Menu menu) { mActionBar.createActionBarMenu(R.menu.photo, menu); mHaveImageEditor = GalleryUtils.isEditorAvailable(mActivity, "image/*"); updateMenuOperations(); mActionBar.setTitle(mMediaSet != null ? mMediaSet.getName() : ""); return true; } }
2 菜单命令的执行。
Gallery的父类是AbstractGalleryActivity类,AbstractGalleryActivity的父类是Activity类。所以菜单创建是调用的AbstractGalleryActivity的菜单命令执行函数。
public class AbstractGalleryActivity extends Activity implements GalleryContext { private static final String TAG = "AbstractGalleryActivity"; private StateManager mStateManager; @Override public boolean onOptionsItemSelected(MenuItem item) { GLRoot root = getGLRoot(); root.lockRenderThread(); try { return getStateManager().itemSelected(item); } finally { root.unlockRenderThread(); } } }
StateManager再将菜单命令分发给当前显示的子页面(以PhotoPage为例)
public class StateManager { private static final String TAG = "StateManager"; private AbstractGalleryActivity mActivity; private Stack<StateEntry> mStack = new Stack<StateEntry>(); public boolean itemSelected(MenuItem item) { if (!mStack.isEmpty()) { if (getTopState().onItemSelected(item)) return true; if (item.getItemId() == android.R.id.home) { if (mStack.size() > 1) { getTopState().onBackPressed(); } return true; } } return false; } }
当前显示的子页面(以PhotoPage为例),最终承担命令的执行工作。其中涉及到文件操作,又会分发到MenuExecutor处理。比如删除操作,MenuExecutor内部会生成一个删除任务,然后交给线程池执行该任务,有兴趣可以看下这部分代码,这里就省略掉了。采用任务-线程池的方式优点是:耗时操作,界面不会卡顿;任务可以随时取消,快速多次操作不影响系统流畅度和稳定性。
public class PhotoPage extends ActivityState{ private static final String TAG = "PhotoPage"; @Override protected boolean onItemSelected(MenuItem item) { MediaItem current = mModel.getMediaItem(0); int currentIndex = mModel.getCurrentIndex(); Path path = current.getPath(); DataManager manager = mActivity.getDataManager(); int action = item.getItemId(); String confirmMsg = null; switch (action) { case R.id.action_edit: { launchPhotoEditor();return true; } case R.id.action_details: { showDetails();return true; } case R.id.action_delete: confirmMsg = mActivity.getResources().getQuantityString( R.plurals.delete_selection, 1); mMenuExecutor.onMenuClicked(item, confirmMsg, new ImportCompleteListener(mActivity)); } } }
三 后续代码分析,大致提纲
Android4.0图库Gallery2代码分析(三) 状态管理和窗口切换
Android4.2图库Gallery3D(Gallery2)分析(四) 菜单命令执行过程分析
Android4.2图库Gallery2代码分析(五) 各种数据源和数据源的管理
Android4.2图库Gallery2代码分析(六) 可渲染数据元及其多样性
Android4.2图库Gallery2代码分析(七) 遥控器控制的实现
Android4.2图库Gallery2代码分析(八) 和数据扫描线程的数据交互
Android4.2图库Gallery2代码分析(九) 几点可优化的地方