下面我要分享一下这几天看源码中获得正在运行进程的简单流程:
也就是图中所看到的
首先我们看到的是settings下的application(应用程序)下的manageApplication(管理应用程序)下的页面,那么要了解其流程,我们就得到源码中去分析:
那么我们到源码下的package/app/Settings/src/com/android/settings下去找相关代码,首先我们根据名称大概可以找到ApplicationSettings.java文件,这个显而易见
并且它加载了application_settings.xml文件,当然在application_settings.xml文件中我们也能找到管理应用程序的组件:
<PreferenceScreen
android:title="@string/manageapplications_settings_title"
android:summary="@string/manageapplications_settings_summary">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.ManageApplications" />
</PreferenceScreen>
但是在ApplicationSettings.java文件中却找不到关于管理应用程序的组件的相关代码和实现的功能,因此我们再去找下有那个文件是管理应用程序相关代码和实现的功能,
当然我们能找到,那就是ManagerApplication.java文件,从图形界面中我们可以看到在顶端是由一个TabHost,所以我们就到文件中去找这个TabHost:
因此我们在Oncreate方法中找到了:
................
mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
R.id.running_processes);
final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec(TAB_DOWNLOADED)
.setIndicator(getString(R.string.filter_apps_third_party),
getResources().getDrawable(R.drawable.ic_tab_download))
.setContent(this));
tabHost.addTab(tabHost.newTabSpec(TAB_ALL)
.setIndicator(getString(R.string.filter_apps_all),
getResources().getDrawable(R.drawable.ic_tab_all))
.setContent(this));
tabHost.addTab(tabHost.newTabSpec(TAB_SDCARD)
.setIndicator(getString(R.string.filter_apps_onsdcard),
getResources().getDrawable(R.drawable.ic_tab_sdcard))
.setContent(this));
tabHost.addTab(tabHost.newTabSpec(TAB_RUNNING)
.setIndicator(getString(R.string.filter_apps_running),
getResources().getDrawable(R.drawable.ic_tab_running))
.setContent(this));
tabHost.setCurrentTabByTag(defaultTabTag);
tabHost.setOnTabChangedListener(this);
.......................
在界面中其实是由菜单键的,这我们知道,因此在其中我们可以找到 onCreateOptionsMenu(Menu menu) 方法创建菜单,onPrepareOptionsMenu准备菜单
以及相应菜单方法onOptionsItemSelected(MenuItem item) ,而在相应菜单中当我们是点击正在运行的子TabHost时,它的菜单项有两个,一个是显示service,一个是显示
缓存的进程:
.............................
else if (menuId == SHOW_RUNNING_SERVICES) {
mRunningProcessesView.mAdapter.setShowBackground(false);
} else if (menuId == SHOW_BACKGROUND_PROCESSES) {
mRunningProcessesView.mAdapter.setShowBackground(true);
}
.....................................
因为主要将的是获取正在运行的进程,所以其它三个子TabHost就不讲了,感兴趣的自己去分析吧,
那么显然这两个子菜单显示的不一样,但是无论点击那一个子菜单都会调用setShowBackground(。。。)方法。当menuId == SHOW_RUNNING_SERVICES时显示的是
service,那么我们就跟踪代码下
去,mRunningProcessesView.mAdapter.setShowBackground(false),调用RunningProcessView.java中的setShowBackground(boolean showBackground) 方法
在setShowBackground中又调用了refreshItems()方法,我们看一看 :
void refreshItems() {
//mState.getCurrentBackgroundItems() is get cache process
//mState.getCurrentMergedItems() is get services
ArrayList<RunningState.MergedItem> newItems =
mShowBackground ? mState.getCurrentBackgroundItems()
: mState.getCurrentMergedItems();
//for(int i=0;i< mState.mBackgroundItems.size();i++)
// Log.i("processName","processName"+ mState.mBackgroundItems.get(i));
// Log.i("number","number="+ mState.getCurrentBackgroundItems().size());
if (mItems != newItems) {
mItems = newItems;
}
if (mItems == null) {
mItems = new ArrayList<RunningState.MergedItem>();
}
}
根据mShowBackground的值,也就是mRunningProcessesView.mAdapter.setShowBackground(false)中传下来的这个boolean值来判断是显示service还是
进程。
mState.getCurrentBackgroundItems()是得到缓存进程的列表,而mState.getCurrentMergedItems() 是得到services的列表,并且他们都是来自RunningStatus.java:
..................................
ArrayList<MergedItem> getCurrentMergedItems() {
synchronized (mLock) {
return mMergedItems;
}
}
ArrayList<MergedItem> getCurrentBackgroundItems() {
synchronized (mLock) {
return mBackgroundItems;
}
.................................
那么我就来看一看怎样得到mMergedItems和mBackgroundItems的两个list:
我们可以发现在一开是就定义了
ArrayList<MergedItem> mMergedItems = new ArrayList<MergedItem>();
ArrayList<MergedItem> mBackgroundItems = new ArrayList<MergedItem>();
而且在private boolean update(Context context, ActivityManager am) 方法中去得到它们(具体的在这个方法中,自己仔细分析吧,我自己有也看得晕晕的):
在private boolean update(Context context, ActivityManager am) 方法中有得到当前的正在运行的服务和进程:
..........................
List<ActivityManager.RunningServiceInfo> services
= am.getRunningServices(MAX_SERVICES);
.............................
.............................
List<ActivityManager.RunningAppProcessInfo> processes
= am.getRunningAppProcesses();
........................
那么在这里就必须要提一下ActivityManager了(framework/base/core/java/android/app/ActivityManager.java):
ActivityManager是android框架的一个重要部分,它负责一新ActivityThread进程创建,Activity生命周期的维护,
它提供了我们管理Activity的一些基本的方法
如下:
public void testgetRecentTasks()
//获取最近的应用,最后启动的排前
public void testgetRunningTasks()
//获取当前运行的Activity应用
public void testgetRunningServices()
//获取当前运行的service应用
public void testgetRunningAppProcesses()
//获取所用系统运行的进程
当然我们所讲的获取系统运行的进程和运行的service应用都是来自ActivityManager这个类中的方法,而且在长按home键显示最近使用的应用程序也是
使用ActivityManager类中的获取最近使用的应用程序getRecentTasks()方法。