Android基礎【1】殺死進程(強行停止)應用程序的方法


寫在前面: 進入手機ODM已經很久,經歷過幾個項目項目下來,對高通、展訊、Marvell平台都進行了接觸,對於我個人來說,參與手機系統項目的開發與維護,最明顯的好處是可以深入的了解某一功能的具體實現過程,以及Android的設計框架,能夠以框架的思維去修改代碼添加功能。入行這么久,越來越覺得有必要將自己在實際工作過程中看到的,領悟到的一些東西能夠記憶下來,並分享出來。 從這篇開始我將會篩選出一些常用功能在Google源碼中的標准方法與大家一起分享,對於我個人來講,比較喜歡按照源碼中已經存在了的標准方法去coding。 首先共享的是 殺死進程的方法, 一般手機管家類應用最基本的就是清理進程的功能。其實這個功能在源碼里面來看是很簡單的,主要有兩步驟:1.獲取正在運行的進程列表;2.根據packageName選擇怎樣去殺掉。 2015.05.06 更新一種方法,利用反射機制調用ActivityManagerService::forceStopPackage來殺掉進程(適用於usr組,但仍然不一定成功)。 這部分的功能主要參考了 1. 設置--應用--正在運行--停止所有進程 2. 任意界面--長按Home--清理最近進程 設置中獲取所用應用程序的做法: 主要使用PackageManager::getInstalledApplications(int flags){} 方法 [java] view plaincopy final int mRetrieveFlags; List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>(); // Only the owner can see all apps. 
        if (UserHandle.myUserId() == 0) { mRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS; } else { mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS; } // 獲取系統中的所有包 
        <strong>mApplications = mPm.getInstalledApplications(mRetrieveFlags);</strong>  
        if (mApplications == null) { mApplications = new ArrayList<ApplicationInfo>(); } for (int i=0; i<mApplications.size(); i++) { final ApplicationInfo info = mApplications.get(i); // Need to trim out any applications that are disabled by // something different than the user. 
            if (!info.enabled) { //此處很有必要,獲取未被禁止的且允許被操作的包 
                if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { mApplications.remove(i); i--; continue; } mHaveDisabledApps = true; } } 標准方法獲取正在運行的進程: 主要使用ActivityManagerService::getRunningAppProcesses(){} 方法 [java] view plaincopy // Temporary structure used when updating above information. 
final SparseArray<AppProcessInfo> mTmpAppProcesses = new SparseArray<AppProcessInfo>(); // Retrieve list of running processes, organizing them into a sparse // array for easy retrieval. 
    List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses(); // 獲取正在運行的進程 
    final int NP = processes != null ? processes.size() : 0; mTmpAppProcesses.clear(); for (int i=0; i<NP; i++) { ActivityManager.RunningAppProcessInfo pi = processes.get(i); mTmpAppProcesses.put(pi.pid, new AppProcessInfo(pi)); } 殺死正在運行進程的方法: 適合api LEVEL <= 7 權限 android.permission.RESTART_PACKAGE [java] view plaincopy private void killPackage(String pkgName) { ActivityManager am = (ActivityManager)getActivity().getSystemService( Context.ACTIVITY_SERVICE); am.restartPackage(pkgName); } 適合api LEVEL >=8 權限 android.permission.KILL_BACKGORUND_PROCESSES [java] view plaincopy private void killPackage(String pkgName) { ActivityManager am = (ActivityManager)getActivity().getSystemService( Context.ACTIVITY_SERVICE); am.killBackgroundProcesses(pkgName); } 設置--應用--詳細--強制停止: 對於非System組進程,無法調用ActivityManager::forceStopPackage(String){}方法,只能嘗試使用ActivityManagerService::forceStopPackage(final String packageName, int userId) 並且不一定能成功,設置中的邏輯大致如下: [java] view plaincopy private DevicePolicyManager mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updateForceStopButton(getResultCode() != Activity.RESULT_CANCELED); } }; private void updateForceStopButton(boolean enabled) { mForceStopButton.setEnabled(enabled); mForceStopButton.setOnClickListener(InstalledAppDetails.this); } private void checkForceStop() { if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { // User can't force stop device admin. 
        updateForceStopButton(false); } else if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) { // If the app isn't explicitly stopped, then always show the // force stop button. 
        updateForceStopButton(true); } else { Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, Uri.fromParts("package", mAppEntry.info.packageName, null)); intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName }); intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid); intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid)); getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); } } [java] view plaincopy private void forceStopPackage(String pkgName) { ActivityManager am = (ActivityManager)getActivity().getSystemService( Context.ACTIVITY_SERVICE); am.forceStopPackage(pkgName); // 不一定成功 
    mState.invalidatePackage(pkgName); // 強制停止后重新獲取一下包信息 
    ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName); if (newEnt != null) { mAppEntry = newEnt; } checkForceStop(); // 最后檢驗是否強停成功(體現在“強行停止”按鈕是否置灰) 
} 在調試過程中,強行停止某一進程的方法是: adb shell am force-stop <package> 比如: am force-stop com.android.launcher 另外 am kill <package> 安全模式下殺死進程,不影響體驗 附: am force-stop: force stop everything associated with <PACKAGE>. --user <USER_ID> | all | current: Specify user to force stop; all users if not specified. am kill: Kill all processes associated with <PACKAGE>. Only kills. processes that are safe to kill -- that is, will not impact the user experience. --user <USER_ID> | all | current: Specify user whose processes to kill; all users if not specified. am kill-all: Kill all background processes. 第三種方法: 通過反射機制,殺死進程 [java] view plaincopy package com.example.androidtest; import android.app.ActivityManager; import android.content.Context; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 通過Java的反射機制強制殺死進程 * @author hanhao * */  
public class ForceKillProgress { public static void forceStopProgress(Context context, String pkgName) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); try { Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class); forceStopPackage.setAccessible(true); forceStopPackage.invoke(am, pkgName); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM