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文件中。


2.    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的系统。