1. 程式人生 > >Android中獲取系統記憶體資訊以及程序資訊-----ActivityManager的使用(一)

Android中獲取系統記憶體資訊以及程序資訊-----ActivityManager的使用(一)

                                                                                                         轉載請註明出處:http://blog.csdn.net/qinjuning

                  本節內容主要是講解ActivityManager的使用,通過ActivityManager我們可以獲得系統里正在執行的activities,包括

     程序(Process)等、應用程式/包、服務(Service)、任務(Task)資訊。

              計劃如下:

                  第一部分:獲取系統可用記憶體以及所有的正在執行的程序資訊 ;

                  第二部分:獲取每個程序裡執行的應用程式資訊和所有正在執行的應用程式

                  第三部分:獲取正在執行的服務和任務資訊。

                每部分都準備了相應的Demo,助您更深的理解.

        知識準備:Android 應用程式模組: 應用、任務、程序的知識介紹:

            1  一個android 包(簡稱.apk) :裡面包含應用程式的程式碼以及資源。這是一個應用釋出,使用者能下載並安裝他們

              裝置上的檔案。

            2  一個 任務 :通常使用者能當它為一個“應用程式”來啟動:通常在桌面上會有一個圖示可以來啟動任務,這是一個

              上層的應用,可以將你的任務切換到前臺來。

            3  一個 程序 :是一個底層的程式碼執行級別的核心程序。通常.apk包裡所有程式碼執行在一個程序裡,一個程序對於

              一個.apk包;然而,程序 標籤常用來改變程式碼執行的位置,可以是全部的.apk包 或者是獨立的活動,接收器,服務, 或者

                 提供器元件。

  程序

         在Android中,程序是應用程式的完整實現,而不是使用者通常瞭解的那樣。他們主要用途很簡單:

            1、提高穩定性和安全性,將不信任或者不穩定的程式碼移動到其他程序。

            2、可將多個.apk包執行在同一個程序裡減少系統開銷。

            3、幫助系統管理資源,將重要的程式碼放在一個單獨的程序裡,這樣就可以單獨銷燬應用程式的其他部分。

         於是,為了完成某一任務或者減少系統資源的開銷,一個程序裡可以執行一個或多個應用程式

ActivityManager 類:

             獲取方法 ActivityManager mActivityManager (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

          常用的靜態內部類如下(下面具體介紹):

 常用方法:

public void getMemoryInfo(ActivityManager.MemoryInfo outInfo)

                說明:獲取系統可用記憶體資訊,資料封裝在outInfo物件上

public Debug.MemoryInfo getProcessMemoryInfo(int[ ] pids

說明:獲取每個程序ID(集合)佔用的記憶體大小(集合), pid和MemoryInfo是一一對應的。

     引數: pids 程序ID的集合

PS :我們可以通過呼叫Debug.MemoryInfo 的dalvikPrivateDirty欄位獲取程序佔用的記憶體大小(單位為KB)

 public List<ActivityManager.RunningAppProcessInfo>getRunningAppProcess()

    說明: 獲取系統里正在執行的程序

               說明:獲取系統里正在執行的服務

               引數: 同上

             說明:獲取系統裡最近啟動的任務

             引數: 同上,flags一般為0即可

public voidkillBackgroundProcess(String packageName)

            說明:立即殺掉給定包名的程序,釋放程序佔用的資源(記憶體等),如果需要,系統會再次重新啟動該程序。系統

            PS:系統程序是殺不死的,只能殺死使用者程序。但我沒有找到好的方法辨別系統程序還是使用者程序。但可以肯定的是,

                   能夠殺死的一定是使用者程序。

          public void restartPackage(String packageName)

            說明:該方法已棄用,等同於killBackgroundProcess 。

 ActivityManager.MemoryInfo類

    常用欄位:

            long availMem 系統可用記憶體

            long threshold系統記憶體不足的閥值,即臨界值

            boolean lowMemory 如果當前可用記憶體<=threshold,該值為真

ActivityManager.RunningAppProcessInfo類

   常用欄位:

          int pid                             程序ID

          int uid                             程序所在的使用者ID

          String processName    程序名,預設是包名或者由android:process=””屬性指定

          String [ ] pkgList           執行在該程序下的所有應用程式包名

   類的介紹留在後文介紹。

DEMO說明:

          我們通過ActivityManager獲取了系統的可用記憶體資訊以及正在執行在系統裡的程序具體資訊,當然你也可以選擇

       手動殺死這些程序,不過前提是使用者程序,因為系統程序是殺不死的。

          模擬器上的截圖如下:

                                    

資原始檔什麼的就不再貼程式碼了,直接列出邏輯檔案。

  獲取系統可用記憶體的程式碼:MainActivity.java

[java] view plain copy print?
  1. package com.qin.ammp;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.app.Activity;  
  5. import android.app.ActivityManager;  
  6. import android.app.ActivityManager.MemoryInfo;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.os.Debug;  
  11. import android.text.format.Formatter;  
  12. import android.util.Log;  
  13. import android.view.View;  
  14. import android.widget.Button;  
  15. import android.widget.TextView;  
  16. publicclass MainActivity extends Activity {  
  17.     privatestatic String TAG = "AM_MEMORYIPROCESS" ;  
  18.     private ActivityManager mActivityManager = null ;  
  19.     private TextView tvAvailMem  ;  
  20.     private Button btProcessInfo ;  
  21.     /** Called when the activity is first created. */
  22.     @Override
  23.     publicvoid onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.main);  
  26.         tvAvailMem = (TextView)findViewById(R.id.tvAvailMemory) ;  
  27.         btProcessInfo =(Button)findViewById(R.id.btProcessInfo);  
  28.         //跳轉到顯示程序資訊介面
  29.         btProcessInfo.setOnClickListener(new View.OnClickListener() {  
  30.             @Override
  31.             publicvoid onClick(View v) {  
  32.                 // TODO Auto-generated method stub
  33.                 Intent intent = new Intent(MainActivity.this,BrowseProcessInfoActivity.class);  
  34.                 startActivity(intent);  
  35.             }  
  36.         });                 
  37.         //獲得ActivityManager服務的物件
  38.         mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);  
  39.         //獲得可用記憶體資訊
  40.         String availMemStr = getSystemAvaialbeMemorySize();  
  41.         Log.i(TAG, "The Availabel Memory Size is"+availMemStr);   
  42.         //顯示
  43.         tvAvailMem.setText(availMemStr);   
  44.     }  
  45.     //獲得系統可用記憶體資訊
  46.     private String getSystemAvaialbeMemorySize(){  
  47.         //獲得MemoryInfo物件
  48.         MemoryInfo memoryInfo = new MemoryInfo() ;  
  49.         //獲得系統可用記憶體,儲存在MemoryInfo物件上
  50.         mActivityManager.getMemoryInfo(memoryInfo) ;  
  51.         long memSize = memoryInfo.availMem ;  
  52.         //字元型別轉換
  53.         String availMemStr = formateFileSize(memSize);  
  54.         return availMemStr ;  
  55.     }  
  56.     //呼叫系統函式,字串轉換 long -String KB/MB
  57.     private String formateFileSize(long size){  
  58.         return Formatter.formatFileSize(MainActivity.this, size);   
  59.     }  
  60. }  
package com.qin.ammp;


import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private static String TAG = "AM_MEMORYIPROCESS" ;
	
	private ActivityManager mActivityManager = null ;
	
	private TextView tvAvailMem  ;
	private Button btProcessInfo ;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tvAvailMem = (TextView)findViewById(R.id.tvAvailMemory) ;
        btProcessInfo =(Button)findViewById(R.id.btProcessInfo);
        //跳轉到顯示程序資訊介面
        btProcessInfo.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MainActivity.this,BrowseProcessInfoActivity.class);
				startActivity(intent);
			}
		});               
        
        //獲得ActivityManager服務的物件
        mActivityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
      
        //獲得可用記憶體資訊
        String availMemStr = getSystemAvaialbeMemorySize();
        Log.i(TAG, "The Availabel Memory Size is"+availMemStr); 
        //顯示
        tvAvailMem.setText(availMemStr); 
        
    }
    //獲得系統可用記憶體資訊
    private String getSystemAvaialbeMemorySize(){
    	//獲得MemoryInfo物件
        MemoryInfo memoryInfo = new MemoryInfo() ;
        //獲得系統可用記憶體,儲存在MemoryInfo物件上
        mActivityManager.getMemoryInfo(memoryInfo) ;
        long memSize = memoryInfo.availMem ;
        
        //字元型別轉換
        String availMemStr = formateFileSize(memSize);
        
        return availMemStr ;
    }
  
    //呼叫系統函式,字串轉換 long -String KB/MB
    private String formateFileSize(long size){
    	return Formatter.formatFileSize(MainActivity.this, size); 
    }
    
}


獲取系統程序資訊的程式碼 :BrowseProcessInfoActivity .java

[java] view plain copy print?
  1. package com.qin.ammp;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.app.Activity;  
  5. import android.app.ActivityManager;  
  6. import android.app.AlertDialog;  
  7. import android.app.Dialog;  
  8. import android.content.Context;  
  9. import android.content.DialogInterface;  
  10. import android.os.Bundle;  
  11. import android.os.Debug;  
  12. import android.util.Log;  
  13. import android.view.ContextMenu;  
  14. import android.view.Menu;  
  15. import android.view.MenuItem;  
  16. import android.view.View;  
  17. import android.view.ContextMenu.ContextMenuInfo;  
  18. import android.widget.AdapterView;  
  19. import android.widget.ListView;  
  20. import android.widget.TextView;  
  21. import android.widget.AdapterView.OnItemClickListener;  
  22. publicclass BrowseProcessInfoActivity extends Activity  implements OnItemClickListener{  
  23.     privatestatic String TAG = "ProcessInfo";  
  24.     privatestaticfinalint KILL_PORCESS = 1;  
  25.     privatestaticfinalint SEARCH_RUNNING_APP = 2;  
  26.     private ActivityManager mActivityManager = null;  
  27.     // ProcessInfo Model類 用來儲存所有程序資訊
  28.     private List<ProcessInfo> processInfoList = null;  
  29.     private ListView listviewProcess;  
  30.     private TextView tvTotalProcessNo ;   
  31.     publicvoid onCreate(Bundle savedInstanceState) {  
  32.         super.onCreate(savedInstanceState);  
  33.         setContentView(R.layout.browse_process_list);  
  34.         listviewProcess = (ListView) findViewById(R.id.listviewProcess);  
  35.         listviewProcess.setOnItemClickListener(this);  
  36.         tvTotalProcessNo =(TextView)findViewById(R.id.tvTotalProcessNo);  
  37.         this.registerForContextMenu(listviewProcess);  
  38.         // 獲得ActivityManager服務的物件
  39.         mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
  40.         // 獲得系統程序資訊
  41.         getRunningAppProcessInfo();  
  42.         // 為ListView構建介面卡物件
  43.         BrowseProcessInfoAdapter mprocessInfoAdapter = new BrowseProcessInfoAdapter(  
  44.                 this, processInfoList);  
  45.         listviewProcess.setAdapter(mprocessInfoAdapter);  
  46.         tvTotalProcessNo.setText("當前系統程序共有:"+processInfoList.size());  
  47.     }  
  48.     //殺死該程序,並且重新整理
  49.     @Override
  50.     publicvoid onItemClick(AdapterView<?> arg0, View arg1,  finalint position, long arg3) {  
  51.         // TODO Auto-generated method stub
  52.         new AlertDialog.Builder(this).setMessage("是否殺死該程序")  
  53.         .setPositiveButton("確定"new DialogInterface.OnClickListener() {  
  54.             @Override
  55.             publicvoid onClick(DialogInterface dialog, int which) {  
  56.                 // TODO Auto-generated method stub
  57.                 //殺死該程序,釋放程序佔用的空間
  58.                 mActivityManager.killBackgroundProcesses(processInfoList.get(position).getProcessName());  
  59.                            //重新整理介面
  60.                 getRunningAppProcessInfo() ;  
  61.                 BrowseProcessInfoAdapter mprocessInfoAdapter = new BrowseProcessInfoAdapter(  
  62.                         BrowseProcessInfoActivity.this, processInfoList);  
  63.                 listviewProcess.setAdapter(mprocessInfoAdapter);  
  64.                 tvTotalProcessNo.setText("當前系統程序共有:"+processInfoList.size());  
  65.             }  
  66.         }).setNegativeButton("取消"new DialogInterface.OnClickListener() {  
  67.             @Override
  68.             publicvoid onClick(DialogInterface dialog, int which) {  
  69.                 // TODO Auto-generated method stub
  70.                 dialog.cancel() ;  
  71.             }  
  72.         }).create().show() ;  
  73.     }  
  74.     // 獲得系統程序資訊
  75.     privatevoid getRunningAppProcessInfo() {  
  76.         // ProcessInfo Model類   用來儲存所有程序資訊
  77.         processInfoList = new ArrayList<ProcessInfo>();  
  78.         // 通過呼叫ActivityManager的getRunningAppProcesses()方法獲得系統裡所有正在執行的程序
  79.         List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager  
  80.                 .getRunningAppProcesses();  
  81.         for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {  
  82.             // 程序ID號
  83.             int pid = appProcessInfo.pid;  
  84.             // 使用者ID 類似於Linux的許可權不同,ID也就不同 比如 root等
  85.             int uid = appProcessInfo.uid;  
  86.             // 程序名,預設是包名或者由屬性android:process=""指定
  87.             String processName = appProcessInfo.processName;  
  88.             // 獲得該程序佔用的記憶體
  89.             int[] myMempid = newint[] { pid };  
  90.             // 此MemoryInfo位於android.os.Debug.MemoryInfo包中,用來統計程序的記憶體資訊
  91.             Debug.MemoryInfo[] memoryInfo = mActivityManager  
  92.                     .getProcessMemoryInfo(myMempid);  
  93.             // 獲取程序佔記憶體用資訊 kb單位
  94.             int memSize = memoryInfo[0].dalvikPrivateDirty;  
  95.             Log.i(TAG, "processName: " + processName + "  pid: " + pid  
  96.                     + " uid:" + uid + " memorySize is -->" + memSize + "kb");  
  97.             // 構造一個ProcessInfo物件
  98.             ProcessInfo processInfo = new ProcessInfo();  
  99.             processInfo.setPid(pid);  
  100.             processInfo.setUid(uid);  
  101.             processInfo.setMemSize(memSize);  
  102.             processInfo.setPocessName(processName);  
  103.             processInfoList.add(processInfo);  
  104.             // 獲得每個程序裡執行的應用程式(包),即每個應用程式的包名
  105.             String[] packageList = appProcessInfo.pkgList;  
  106.             Log.i(TAG, "process id is " + pid + "has " + packageList.length);  
  107.             for (String pkg : packageList) {  
  108.                 Log.i(TAG, "packageName " + pkg + " in process id is -->"+ pid);  
  109.             }  
  110.         }  
  111.     }  
  112.     publicvoid onCreateContextMenu(ContextMenu menu, View v,  
  113.             ContextMenuInfo menuInfo) {  
  114.         menu.add(00, KILL_PORCESS, "殺死該程序");  
  115.         menu.add(00, SEARCH_RUNNING_APP, "執行在該程序的應用程式");  
  116.         super.onCreateContextMenu(menu, v, menuInfo);  
  117.     }  
  118.     publicboolean onContextItemSelected(MenuItem item) {  
  119.         switch (item.getItemId()) {  
  120.         case KILL_PORCESS: // 殺死該程序 , 重新載入介面
  121.             new AlertDialog.Builder(this).setMessage("是否殺死該程序")  
  122.             .setPositiveButton("確定"new DialogInterface.OnClickListener() {  
  123.                 @Override
  124.                 publicvoid onClick(DialogInterface dialog, int which) {  
  125.                     // TODO Auto-generated method stub
  126.                 }  
  127.             }).setNegativeButton("取消"new DialogInterface.OnClickListener() {  
  128.                 @Override
  129.                 publicvoid onClick(DialogInterface dialog, int which) {  
  130.                     // TODO Auto-generated method stub
  131.                     dialog.cancel() ;  
  132.                 }  
  133.             }).create().show() ;  
  134.             break;  
  135.         case SEARCH_RUNNING_APP: // 檢視執行在該程序的應用程式資訊
  136.             break;  
  137.         default:  
  138.             break;  
  139.         }  
  140.         returnsuper.onContextItemSelected(item);  
  141.     }  
  142. }  
package com.qin.ammp;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Debug;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class BrowseProcessInfoActivity extends Activity  implements OnItemClickListener{

	private static String TAG = "ProcessInfo";
	private static final int KILL_PORCESS = 1;
	private static final int SEARCH_RUNNING_APP = 2;

	private ActivityManager mActivityManager = null;
	// ProcessInfo Model類 用來儲存所有程序資訊
	private List<ProcessInfo> processInfoList = null;

	private ListView listviewProcess;
    private TextView tvTotalProcessNo ; 
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.browse_process_list);

		listviewProcess = (ListView) findViewById(R.id.listviewProcess);
		listviewProcess.setOnItemClickListener(this);
		
		tvTotalProcessNo =(TextView)findViewById(R.id.tvTotalProcessNo);
		
        this.registerForContextMenu(listviewProcess);
		// 獲得ActivityManager服務的物件
		mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
		// 獲得系統程序資訊
		getRunningAppProcessInfo();
		// 為ListView構建介面卡物件
		BrowseProcessInfoAdapter mprocessInfoAdapter = new BrowseProcessInfoAdapter(
				this, processInfoList);
		listviewProcess.setAdapter(mprocessInfoAdapter);
	
		tvTotalProcessNo.setText("當前系統程序共有:"+processInfoList.size());
	}
    //殺死該程序,並且重新整理
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1,  final int position, long arg3) {
		// TODO Auto-generated method stub
	    new AlertDialog.Builder(this).setMessage("是否殺死該程序")
	    .setPositiveButton("確定", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				//殺死該程序,釋放程序佔用的空間
				mActivityManager.killBackgroundProcesses(processInfoList.get(position).getProcessName());
		                   //重新整理介面
				getRunningAppProcessInfo() ;
				BrowseProcessInfoAdapter mprocessInfoAdapter = new BrowseProcessInfoAdapter(
						BrowseProcessInfoActivity.this, processInfoList);
				listviewProcess.setAdapter(mprocessInfoAdapter);
				tvTotalProcessNo.setText("當前系統程序共有:"+processInfoList.size());

			}
		}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel() ;
			}
		}).create().show() ;
	}
	// 獲得系統程序資訊
	private void getRunningAppProcessInfo() {
		// ProcessInfo Model類   用來儲存所有程序資訊
	    processInfoList = new ArrayList<ProcessInfo>();

		// 通過呼叫ActivityManager的getRunningAppProcesses()方法獲得系統裡所有正在執行的程序
		List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager
				.getRunningAppProcesses();

		for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {
			// 程序ID號
			int pid = appProcessInfo.pid;
			// 使用者ID 類似於Linux的許可權不同,ID也就不同 比如 root等
			int uid = appProcessInfo.uid;
			// 程序名,預設是包名或者由屬性android:process=""指定
			String processName = appProcessInfo.processName;
			// 獲得該程序佔用的記憶體
			int[] myMempid = new int[] { pid };
			// 此MemoryInfo位於android.os.Debug.MemoryInfo包中,用來統計程序的記憶體資訊
			Debug.MemoryInfo[] memoryInfo = mActivityManager
					.getProcessMemoryInfo(myMempid);
			// 獲取程序佔記憶體用資訊 kb單位
			int memSize = memoryInfo[0].dalvikPrivateDirty;

			Log.i(TAG, "processName: " + processName + "  pid: " + pid
					+ " uid:" + uid + " memorySize is -->" + memSize + "kb");
			// 構造一個ProcessInfo物件
			ProcessInfo processInfo = new ProcessInfo();
			processInfo.setPid(pid);
			processInfo.setUid(uid);
			processInfo.setMemSize(memSize);
			processInfo.setPocessName(processName);
			processInfoList.add(processInfo);

			// 獲得每個程序裡執行的應用程式(包),即每個應用程式的包名
			String[] packageList = appProcessInfo.pkgList;
			Log.i(TAG, "process id is " + pid + "has " + packageList.length);
			for (String pkg : packageList) {
				Log.i(TAG, "packageName " + pkg + " in process id is -->"+ pid);
			}
		}
	}

	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.add(0, 0, KILL_PORCESS, "殺死該程序");
		menu.add(0, 0, SEARCH_RUNNING_APP, "執行在該程序的應用程式");
		super.onCreateContextMenu(menu, v, menuInfo);

	}

	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case KILL_PORCESS: // 殺死該程序 , 重新載入介面
		    new AlertDialog.Builder(this).setMessage("是否殺死該程序")
		    .setPositiveButton("確定", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					
				}
			}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					dialog.cancel() ;
				}
			}).create().show() ;
			break;
		case SEARCH_RUNNING_APP: // 檢視執行在該程序的應用程式資訊
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
	}

}


   我們可以通過程序佔用記憶體大小來進而獲取佔用cpu大小,直接換算還是很簡單的。

http://blog.csdn.net/qinjuning/article/details/6978560