2012-03-21 53 views

回答

25

我再次回答的時間太晚了,但由於我今天在相同的情況下運行,我想分享我的發現以幫助某人。

首先你需要了解你可以什麼不是。從Android的角度來看,應用程序不像其他操作系統。一個Android應用程序由包裝在一個包中的許多組件(活動,廣播接收器,服務,最重要的任務等)組成。一個程序包可以有多個運行的進程,具體取決於其運行的組件。

現在最有趣的部分是一個Android軟件包沒有(由Android)殺死停止如果過程中的任何或全部殺死,其實包仍可甚至沒有任何進程在運行考慮一直運行。你可以看到這個效果,如果你開始的仿真器,啓動程序(IE瀏覽器),然後通過DDMS殺死它的進程,之後去到應用程序的包設置(Settings --> Applications --> Manage Applications --> All --> Browser),你可以看到啓用強制停止按鈕,這意味着應用程序仍在運行(從Android的角度來看)。這裏發生的事情是,應用程序有一個或多個任務冷凍。也就是說,Android已經保存了應用程序活動(任務或任務)的狀態,所以如果用戶返回,那麼程序包仍然運行或更好,他將着陸他正在做的最後一件事。現在,如果你點擊強制停止按鈕,Android將放棄所有的這些冷凍任務,當用戶返回到應用程序,他會看到的第一個活動。 A 任務只有用戶(從強制停止按鈕)不能殺死(從froyo),系統或與系統的相同密鑰簽名的第三方應用程序可以做到這一點(也可能是根有能力的應用程序,但我沒有證實這一點)。在另一方面一個過程是你可以殺死,並收回其佔用的內存,只要你遵循一些限制:

  1. 你有android.permission.KILL_BACKGROUND_PROCESSES權限。
  2. 進程不是系統或根進程。
  3. 該進程不屬於持久性組件。
  4. 該過程對於系統以任何其他方式操作都不是關鍵。

除了第一條規則,您不必對它們做些什麼,Android會照顧到這一點。

ActivityManager有一個方便的功能,你可以用它來殺死一個包一次完成的所有進程。當你調用它時,Android會殺死任何可以被殺死的進程,從而釋放一些內存。然而,這個包的任務狀態將被保存,當用戶返回到應用程序時,他會看到他所做的最後一件事情,除非系統本身已經殺死了他們。這可能是因爲它需要資源或狀態很久以前被保存(大約30分鐘)。副作用是因爲用戶認爲所有的應用程序都像桌面操作系統,他們不相信應用程序真的關閉了,但這是android的生活。

現在編碼:

對於我的項目,我準備了三個功能來實現這個功能。

第一個查找包中可能包含的第一個進程pid,如果沒有,則返回-1。

private Context cx; 
private ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE); 

public int findPIDbyPackageName(String packagename) { 
    int result = -1; 

    if (am != null) { 
     for (RunningAppProcessInfo pi : am.getRunningAppProcesses()){ 
      if (pi.processName.equalsIgnoreCase(packagename)) { 
       result = pi.pid; 
      } 
      if (result != -1) break; 
     } 
    } else { 
     result = -1; 
    } 

    return result; 
} 

第二個做一些愚蠢的事,但我需要它爲我的項目。

public boolean isPackageRunning(String packagename) { 
    return findPIDbyPackageName(packagename) != -1; 
} 

第三個工作。

public boolean killPackageProcesses(String packagename) { 
    boolean result = false; 

    if (am != null) { 
     am.killBackgroundProcesses(packagename); 
     result = !isPackageRunning(packagename); 
    } else { 
     result = false; 
    } 

    return result; 
} 

他們證實API 15與仿真器API 8,9和實際設備(銀河S2)上工作,他們盡殺任何應用程序的進程(不僅僅是你自己的),只要他們不需要。

現在談談android.os.Process.killProcess文檔其中指出:

...通常,這意味着只有進程中運行呼叫者的包/應用程序,通過該應用程序創建的任何額外的過程; ...

我相信「運行呼叫者的包/應用程序的進程」意味着家庭啓動應用程序而不是在你自己的應用程序。您的應用程序是調用者,並且運行調用者程序包/應用程序的進程是家庭啓動器或任何其他應用程序啓動您的應用程序。這是我解釋killBackgroundProcesses函數和android.os.Process.killProcess函數確實可用於第三方應用程序的唯一方法。

+0

謝謝你的完整答案! – 2012-05-07 07:24:36

+0

絕妙的解釋.. – 2014-12-19 19:57:38

1

站在DOC:

殺死與所述給定PID的過程。請注意,雖然此API允許我們根據其PID來請求終止任何進程,但內核仍會對您確實能夠殺死的PID施加標準限制。通常這意味着只有運行調用者的程序包/應用程序以及由該應用程序創建的任何其他進程的進程;共享一個通用UID的軟件包也能夠殺死對方的進程。

,所以你可以殺死自己的進程..

看到Process文檔。我試圖運行adb shell kill pid,但它需要超級用戶權限

+0

我知道我可以殺死我自己的進程,我的問題是如何殺死外部進程。 – 2012-03-21 13:22:43

+1

據我所知,你不能,如果你沒有權利殺死那個過程 – Blackbelt 2012-03-21 13:25:14

+0

是<如何殺死外國進程?<< – Criss 2015-03-30 09:16:56