Android源码之应用程序界面分析一(从settings开始):
一。 预热:
当我们点击"设置” ->“应用程序”中时,会出现应用程序的列表,而且,有“所有应用”,“已下载”如,“正在运行”等Tab,那么,这个界面是如何实现的呢,那就要看settings应用的相关源码了。二。源码分析:
1。入口:ManageApplications.java,
这个类就是上面功能的实现类,它继承自ListActivity(2.2版本,3.0时已改为fragment)。
下面,仅仅列出几个数据成员,先来看一下:
FILTER_APPS_ALL // 标记所有app
FILTER_APPS_THIRD_PARTY // 标记第三方app
FILTER_APPS_RUNNING //标记正在运行的app
PkgSizeObserver mObserver;//用于得到package详细信息的回调类。
1)。 在onCreate中,
List<ApplicationInfo> appList = getInstalledApps(mSortOrder);
mAppInfoAdapter = new AppInfoAdapter(this, appList);
ListView lv= (ListView) findViewById(android.R.id.list);
lv.setOnItemClickListener(this);
这样,就列出了已安装的应用程序的列表。
2)。当用户点击"全部","sdcard",或者"正在运行"中的任意一个的时候,onClick会被调用:
在onItemClick中, 会通过sendMessageToHandler来通知UI,更新新的appList.
3) 。当用户选择一个app时,会显示这个应用的详细信息。这是通过调用onItemClick函数来实现的,如下:
在onItemClick这个函数中:会调用startApplicationDetailsActivity,从而列出选择的app的详细信息。这样,就进入到InstalledAppDetails.java文件中。
在这个类中,关注以下几点:
1)。 在onCreate中:
PackageManager mPm = getPackageManager();
mSizeObserver = new PkgSizeObserver();
mPm.getPackageSizeInfo(packageName, mSizeObserver);
用来得到app的详细信息,再看mSizeObserver 所属的类PkgSizeObserver 的定义,这是InstalledAppDetails的一个内部类。
2)。PkgSizeObserver 的定义:
class PkgSizeObserver extends IPackageStatsObserver.Stub {
public int idx;
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) {
Message msg = mHandler.obtainMessage(GET_PKG_SIZE);
Bundle data = new Bundle();
data.putParcelable(ATTR_PACKAGE_STATS, pStats);
msg.setData(data);
mHandler.sendMessage(msg);
}
}
那么,当mPm.getPackageSizeInfo执行完成后,会回调到onGetStatsCompleted函数中,而这个函数的参数PackageStats pStats
就保存了app的详细信息。这样,通过sendMessage,mHandler就会处理这个消息了,会进入到refreshSizeInfo函数中,在这个函数中,就会将得到的详细信息更新了。
3)。事实上,InstalledAppDetails.java 还定义了以下几个内部类:
用于清理用户数据的类ClearUserDataObserver (对应于UI的"清理数据"):
class ClearUserDataObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(final String packageName, final boolean succeeded) {
final Message msg = mHandler.obtainMessage(CLEAR_USER_DATA);
msg.arg1 = succeeded?OP_SUCCESSFUL:OP_FAILED;
mHandler.sendMessage(msg);
}
}
用于清理缓存的类ClearCacheObserver (对应于UI的"清理缓存"):
class ClearCacheObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(final String packageName, final boolean succeeded) {
final Message msg = mHandler.obtainMessage(CLEAR_CACHE);
msg.arg1 = succeeded?OP_SUCCESSFUL:OP_FAILED;
mHandler.sendMessage(msg);
}
}
可以看出,这些内部类的使用方式基本类似,如下:
都是通过调用Android Framework层的组件来实现具体的功能的。除了本例中的getPackageSizeInfo,再举一例“清理用户数据”:
mClearDataObserver = new ClearUserDataObserver();
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
am.clearApplicationUserData(packageName, mClearDataObserver);
当然,本类中还实现了应用程序的卸载等功能,代码比较简单,这里,不再描述。
3。 再次回顾一下,得到应用程序的详细信息的代码是:
PackageManager mPm = getPackageManager();
mSizeObserver = new PkgSizeObserver();
mPm.getPackageSizeInfo(packageName, mSizeObserver);
三。后记:
1。类似“获取应用程序详细信息”,“清理缓存”,“清理用户数据”, 这些功能,在一些安全类产品中经常会体现;
2。那么,PackageManager的getPackageSizeInfo函数是怎么实现的呢,这就涉及到Android Framework中非常核心的一个组件PackageManager类,从这个类的具体实现过程, 我们完全可以以一斑窥全貌,去了解和理解整个Android的系统。这将在接下来的源码分析文章中进行说明。