本文原创, 转载请注明出处:http://blog.youkuaiyun.com/qinjuning
上上周五的下午,也就是2012.09.07,终于向主管提出了辞职,也下定决心准备返回武汉工作,原因当然
有很多, 在此也不讲这“数不清理还乱的”事儿了,让各位笑话了。
最近,工作倒挺清闲,俗话说“人太闲了,就容易奇思乱想” ,这不我也觉得天马行空了。于是心里一直在
嘀咕着,该做点什么有意义的事情出来,开发一些App第一个浮现在我脑海里。可我脑子不好使,没有很好地
创意。每次和朋友同事聊天,“有想法,其他都是浮云”总是会从我的嘴里蹦出来,可我只能空口说白话,插科
打诨。呵呵,我也希望自己能多点创新的点子,说不定那天我也去创业了呢? 额,话说大了。还是拉回现实吧。
我只能想啊想,思啊思,偶然间联想到博客中之前对应用程序中相关信息的一系列总结,索性横下一条心,先
做个简易的任务管理器吧,所谓“麻雀虽小,五脏俱全”。希望也能在逐步完善这个任务管理器的时候,能够从中
汲取更多关于编码、设计以及效率的问题,自己也会随着这个小东西的完善而逐渐变得强大的。
差不多占用了周末时间以及晚上(我可没加班)时间,做出来了这个雏形,马马虎虎而已。废话不多说了,见
下文。
主要知识来源:
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.youkuaiyun.com/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.youkuaiyun.com/detail/qinjuning/4572769
希望大家能提供宝贵意见。 Over ~~~~