本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning
上上周五的下午,也就是2012.09.07,终于向主管提出了辞职,也下定决心准备返回武汉工作,原因当然
有很多,在此也不讲这“数不清理还乱的”事儿了,让各位笑话了。
最近,工作倒挺清闲,俗话说“人太闲了,就容易奇思乱想” ,这不我也觉得天马行空了。于是心里一直在
嘀咕着,该做点什么有意义的事情出来,开发一些App第一个浮现在我脑海里。可我脑子不好使,没有很好地
创意。每次和朋友同事聊天,“有想法,其他都是浮云”总是会从我的嘴里蹦出来,可我只能空口说白话,插科
打诨。呵呵,我也希望自己能多点创新的点子,说不定那天我也去创业了呢? 额,话说大了。还是拉回现实吧。
我只能想啊想,思啊思,偶然间联想到博客中之前对应用程序中相关信息的一系列总结,索性横下一条心,先
做个简易的任务管理器吧,所谓“麻雀虽小,五脏俱全”。希望也能在逐步完善这个任务管理器的时候,能够从中
汲取更多关于编码、设计以及效率的问题,自己也会随着这个小东西的完善而逐渐变得强大的。
差不多占用了周末时间以及晚上(我可没加班)时间,做出来了这个雏形,马马虎虎而已。废话不多说了,见
下文。
主要知识来源:
1、 <<Android中获取应用程序(包)的信息-----PackageManager的使用(一)>>
2、<<Android中获取应用程序(包)的大小-----PackageManager的使用(二)>>
3、<<Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用>>
4、关于制作底部导航的相关博文如下:
功能说明:
1、分类列出系统已安装程序的信息:icon(修正app icon大小)、lable、size
2、能卸载第三方应用程序
3、更新系统安装程序信息,例如:卸载、安装程序后。
4、查看、停止正在运行的Service
简单点来说,就是把我上面列出的4条单独地个体整理成一个有机的整体,整体才是有生命、充满活力的。
功能简单,程序当然也很简单。 先上图:
工程逻辑图如下:
伪设计说明
使用继承体系
由于我们用于呈现分类的已安装程序的Activity在界面以及功能上大体一致,因此我们将这部分共性(界面等)
抽取出来形成一个抽象父类(BaseActivity),基本上所有功能都由这个抽象父类完成了,子类仅仅提供数据对象。
UML图:
设计缺点
然而,随着后期新功能的加入以及优化,这种在TabActivity中添加Activity的功能已经不能满足需要,甚至
现有设计本身就是欠缺地,只能在后续中重构改善设计。
缺点主要有二:
1、效率比较低下 ---- 需要同时管理多个Activity的生命周期
2、造成了数据之间的过度耦合以及代码冗余 ---- 添加新功能时,发现数据交互之间比较繁杂,例如:添加
一个对ACTION_PACKAGE_XXX的BroadcastReceiver时,需要注册多次,数据交互之间也不很麻烦。
后续优化
计划参考Android2.3 Settings中应用程序功能的实现,采用TabHost.TabContentFactory类为TabActivity提供
视图,在性能上继续优化我们的这个小东西 。
BaseActivity的部分源码如下:
/** @author http://http://blog.csdn.net/qinjuning*/ public abstract class BaseActivity extends Activity implements OnItemClickListener{ private static String TAG = "BaseActivity"; protected ListView mListView = null; protected TextView mTvAppCount = null ; private static PackageManager mPackageManager; protected static List<AppInfo> mAllAppInfoList = new ArrayList<AppInfo>() ; protected static List<AppInfo> mSystemAppInfoList = new ArrayList<AppInfo>(); protected static List<AppInfo> mThirdAppInfoList = new ArrayList<AppInfo>(); protected static List<AppInfo> mSDCardAppInfoList = new ArrayList<AppInfo>(); protected AppInfoAdapter mAppInfoAdapter = null ; //适配器 private PakcageStateChangeReceiver mPackageReceiver = new PakcageStateChangeReceiver(); private static Context mContext ; /** We had loaded the application info*/ private static boolean mHasLoadered = false ; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this ; mPackageManager = this.getApplicationContext().getPackageManager(); if(!mHasLoadered) { mHasLoadered = true ; // we have load the application loadAppInfoList(); } initUI(R.layout.browse_app_list); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addAction(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); filter.addDataScheme("package"); //Attention registerReceiver(mPackageReceiver , filter); } /**设置UI*/ protected void initUI(int resId) { setContentView(resId); mListView = (ListView) findViewById(R.id.listviewApp); mListView.setAdapter(makeAppInfoAdapter()); mListView.setOnItemClickListener(this); mTvAppCount = (TextView)findViewById(R.id.app_type_count); setAppCountView(); } //构建一个BaseAdapter适配器对象,为ListView提供数据 protected BaseAdapter makeAppInfoAdapter() { mAppInfoAdapter = new AppInfoAdapter(this , getAppInfoList()); return mAppInfoAdapter ; } //返回该应用程序适合的容器 protected abstract List<AppInfo> getAppInfoList(); //查询系统应用程序信息并填充到我们的集合中 private static void loadAppInfoList() { // 查询所有已经安装的应用程序 List<ApplicationInfo> listApplications = mPackageManager .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); Slog.v(TAG, "initAppInfoList:: listApplications Size # " + listApplications.size()); Collections.sort(listApplications, new ApplicationInfo.DisplayNameComparator(mPackageManager));// 排序 for(ApplicationInfo applicationInfo : listApplications ) { //构建一个我们的AppInfo Model类 AppInfo appInfo = makeAppInfo(applicationInfo); //获得应用程序大小...信息 try { Utility.queryPacakgeSize(applicationInfo.packageName, mPackageManager , appInfo); } catch(Exception ex) { ex.printStackTrace(); } fillListByFlag(applicationInfo.flags , appInfo); } } // 构造一个AppInfo Model对象 ,并赋值 private static AppInfo makeAppInfo(ApplicationInfo applicationInfo) { ... } //根据Flag标记分别添加至我们的集合中 private static void fillListByFlag(int flags , AppInfo appInfo) { //所有程序 mAllAppInfoList.add(appInfo); //系统内置程序 if((flags & ApplicationInfo.FLAG_SYSTEM) != 0 ) { mSystemAppInfoList.add(appInfo); appInfo.isSystem = true ; } //本来是系统程序,被用户手动更新后,该系统程序也成为第三方应用程序了 else if ((flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0){ mThirdAppInfoList.add(appInfo); } //第三方应用程序 else if ((flags & ApplicationInfo.FLAG_SYSTEM) == 0) { mThirdAppInfoList.add(appInfo); } //安装在SD卡中的程序 if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { mSDCardAppInfoList.add(appInfo); } } private class PakcageStateChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Slog.v(TAG, "onReceive Action --" + action); if(Intent.ACTION_PACKAGE_CHANGED.equals(action) || Intent.ACTION_PACKAGE_ADDED.equals(action)|| Intent.ACTION_PACKAGE_REMOVED.equals(action)) { String pkgName = intent.getData().getSchemeSpecificPart() ; boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); Slog.v(TAG, "pkgName --" + pkgName + " replacing : " + replacing); if(!Intent.ACTION_PACKAGE_CHANGED.equals(action)) { if(Intent.ACTION_PACKAGE_REMOVED.equals(action)) { if(!replacing) //Removed { removeAppInfo(pkgName) ; } else { //We will receiver the ACTION_PACKAGE_ADDED later , // do something there. } } else // ACTION_PACKAGE_ADDED { if(!replacing) // 安装了新的应用程序 { addAppInfo(pkgName) ; } else //更新了应用程序 { updateAppInfo(pkgName); } } } } } } }
其他代码就不在贴了,大家有兴趣的自行研究咯。
分享永远是咱移动互联网的精神, 本次雏形版下载地址,
http://download.csdn.net/detail/qinjuning/4572769
希望大家能提供宝贵意见。 Over ~~~~