今天繼續講解關於ActivityManager的使用,通過前面一節的學習,我們學會了如何利用ActivityManager獲取系統里
正在運行的進程。本文要講解的知識點是利用這些進程信息獲取系統里正在運行的應用程序以及每個進程里運行的應用程序。
用到的知識點也包括PackageManager的使用,讀者閱讀在我之前寫的blog《PackageManager的使用》
每一個應用程序都會運行在它獨立的進程里,但是為了節省資源或者這些應用程序是為了完成某一共同工作,它們
也可能會運行在一個進程里。
知識點介紹:
ActivityManager.RunningAppProcessInfo類
說明: 封裝了正在運行的進程信息
常用字段:
int pid 進程ID
int uid 進程所在的用戶ID
String processName 進程名,默認是包名或者由android:process=””屬性指定
String [ ] pkgList 運行在該進程下的所有應用程序包名
關於ActivityManager.RunningAppProcessInfo更多信息,請查看<Android中應用程序的信息---ActivityManager的使用>
PackageManger類
說明: 封裝了對應用程序信息的操作
獲得應用程序信息的的方法如下:
public abstract ApplicationInfo getApplicationInfo(String packageName, int flags)
參數:packagename 包名
flags 該ApplicationInfo是此flags標記,通常可以直接賦予常數0即可
功能:返回ApplicationInfo對象
關於PackageManger更多信息,請查看<Android中獲取應用程序(包)的信息-----PackageManager的使用(一)>
Demo說明:
我們利用ActivityManager獲取所有正在運行的進程信息后,也就是獲取了每個進程里正在運行的應用程序包名(pkgname),
那么通過這些包名(pkgname),直接調用PackageManager類提供的方法,可以獲取這些應用程序的信息了。
一些資源文件就不貼了,直接貼出了主工程邏輯。需要注意的在這兒我們一次性獲取了所有應用程序信息,然后對這些
應用程序進行過濾,得到我們需要的對象。 讀者可以使用PackageManager類提供的方法,進行循環遍歷所有包名(pkgname),
但是這樣效率會比較低。
截圖如下:
點擊某一進程后 查看某一進程運行的應用程序信息 所有正在運行的進程信息:
顯示正在運行應用程序的工程代碼如下:
- package com.qin.ammp;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import android.app.Activity;
- import android.app.ActivityManager;
- import android.content.Context;
- import android.content.Intent;
- import android.content.pm.ApplicationInfo;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.AdapterView.OnItemClickListener;
- public class BrowseRunningAppActivity extends Activity {
- private static String TAG = "BrowseRunningAppActivity";
- private ListView listview = null;
- private List<RunningAppInfo> mlistAppInfo = null;
- private TextView tvInfo = null ;
- private PackageManager pm;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.browse_app_list);
- listview = (ListView) findViewById(R.id.listviewApp);
- tvInfo = (TextView)findViewById(R.id.tvInfo) ;
- mlistAppInfo = new ArrayList<RunningAppInfo>();
- // 查詢某一特定進程的所有應用程序
- Intent intent = getIntent();
- //是否查詢某一特定pid的應用程序
- int pid = intent.getIntExtra("EXTRA_PROCESS_ID", -1);
- if ( pid != -1) {
- //某一特定經常里所有正在運行的應用程序
- mlistAppInfo =querySpecailPIDRunningAppInfo(intent, pid);
- }
- else{
- // 查詢所有正在運行的應用程序信息: 包括他們所在的進程id和進程名
- tvInfo.setText("所有正在運行的應用程序有-------");
- mlistAppInfo = queryAllRunningAppInfo();
- }
- BrowseRunningAppAdapter browseAppAdapter = new BrowseRunningAppAdapter(this, mlistAppInfo);
- listview.setAdapter(browseAppAdapter);
- }
- // 查詢所有正在運行的應用程序信息: 包括他們所在的進程id和進程名
- // 這兒我直接獲取了系統里安裝的所有應用程序,然后根據報名pkgname過濾獲取所有真正運行的應用程序
- private List<RunningAppInfo> queryAllRunningAppInfo() {
- pm = this.getPackageManager();
- // 查詢所有已經安裝的應用程序
- List<ApplicationInfo> listAppcations = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
- Collections.sort(listAppcations,new ApplicationInfo.DisplayNameComparator(pm));// 排序
- // 保存所有正在運行的包名 以及它所在的進程信息
- Map<String, ActivityManager.RunningAppProcessInfo> pgkProcessAppMap = new HashMap<String, ActivityManager.RunningAppProcessInfo>();
- ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- // 通過調用ActivityManager的getRunningAppProcesses()方法獲得系統里所有正在運行的進程
- List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager
- .getRunningAppProcesses();
- for (ActivityManager.RunningAppProcessInfo appProcess : appProcessList) {
- int pid = appProcess.pid; // pid
- String processName = appProcess.processName; // 進程名
- Log.i(TAG, "processName: " + processName + " pid: " + pid);
- String[] pkgNameList = appProcess.pkgList; // 獲得運行在該進程里的所有應用程序包
- // 輸出所有應用程序的包名
- for (int i = 0; i < pkgNameList.length; i++) {
- String pkgName = pkgNameList[i];
- Log.i(TAG, "packageName " + pkgName + " at index " + i+ " in process " + pid);
- // 加入至map對象里
- pgkProcessAppMap.put(pkgName, appProcess);
- }
- }
- // 保存所有正在運行的應用程序信息
- List<RunningAppInfo> runningAppInfos = new ArrayList<RunningAppInfo>(); // 保存過濾查到的AppInfo
- for (ApplicationInfo app : listAppcations) {
- // 如果該包名存在 則構造一個RunningAppInfo對象
- if (pgkProcessAppMap.containsKey(app.packageName)) {
- // 獲得該packageName的 pid 和 processName
- int pid = pgkProcessAppMap.get(app.packageName).pid;
- String processName = pgkProcessAppMap.get(app.packageName).processName;
- runningAppInfos.add(getAppInfo(app, pid, processName));
- }
- }
- return runningAppInfos;
- }
- // 某一特定經常里所有正在運行的應用程序
- private List<RunningAppInfo> querySpecailPIDRunningAppInfo(Intent intent , int pid) {
- String[] pkgNameList = intent.getStringArrayExtra("EXTRA_PKGNAMELIST");
- String processName = intent.getStringExtra("EXTRA_PROCESS_NAME");
- //update ui
- tvInfo.setText("進程id為"+pid +" 運行的應用程序共有 : "+pkgNameList.length);
- pm = this.getPackageManager();
- // 保存所有正在運行的應用程序信息
- List<RunningAppInfo> runningAppInfos = new ArrayList<RunningAppInfo>(); // 保存過濾查到的AppInfo
- for(int i = 0 ; i<pkgNameList.length ;i++){
- //根據包名查詢特定的ApplicationInfo對象
- ApplicationInfo appInfo;
- try {
- appInfo = pm.getApplicationInfo(pkgNameList[i], 0);
- runningAppInfos.add(getAppInfo(appInfo, pid, processName));
- }
- catch (NameNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } // 0代表沒有任何標記;
- }
- return runningAppInfos ;
- }
- // 構造一個RunningAppInfo對象 ,並賦值
- private RunningAppInfo getAppInfo(ApplicationInfo app, int pid, String processName) {
- RunningAppInfo appInfo = new RunningAppInfo();
- appInfo.setAppLabel((String) app.loadLabel(pm));
- appInfo.setAppIcon(app.loadIcon(pm));
- appInfo.setPkgName(app.packageName);
- appInfo.setPid(pid);
- appInfo.setProcessName(processName);
- return appInfo;
- }
- }
通過對這一節的介紹,我們基本上完成了Android系統里Settings模塊了應用程序的功能,雖然在整體上,並沒有貫穿起來,
但是主軸線已經規划好了,大家也仔細體味吧。