android 如何實現一鍵清理
從事android系統開發有一段時間,一直在想著能夠有一些內容能夠與朋友們分享;同時,也能夠再一次的加深之前解決的問題和原理!開發過程中有時也是通過搜尋各種資料和閱讀各位博主的文章,解決了遇到的問題;在此,也對各位博主和大神表示感謝,這也是我想寫部落格的原因,不能一直是"拿來主義"! 先寫一個比較簡單的例子當作開端! 問題描述:在一次客戶定製的機器上有一音樂apk,在點選最近任務介面的"X"號退出之後仍然能夠播放歌曲 ![一鍵清理圖](https://img-blog.csdn.net/20170913211629401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTWljaGFlbDMxMjkxNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
解決方案:X號的資源id為dismiss_task,原始碼位於frameworks\base\packages\SystemUI\src\com\android\systemui\recents\views\TaskViewHeader.java
該按鍵的點選事件在該類中的
@Override
public void onClick(View v) {
if (v == mIconView) {
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
}
else if (v == mDismissButton) {
**ActivityManager activityManager = (ActivityManager)
getContext().getSystemService(Context.ACTIVITY_SERVICE);*
TaskView tv = Utilities.findParent(this, TaskView.class);
tv.dismissTask();*
**if("清理app的title" .equalsIgnoreCase(mTitleView.getText().toString())){
activityManager.forceStopPackage("清理app的包名");*
}*
// Keep track of deletions by the dismiss button
MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
Constants.Metrics.DismissSourceHeaderButton);
}
.............
}
只需要呼叫ActivityManager的forceStopPackage(String pkgName)方法即可,該函式是系統隱藏函式,其作用是:強制終止指定的apk,包括apk所在的程序及service,並且終止service不會被當做crash而被系統重新啟動起來;因此使用該函式限制因素有:1.整合的app必須放置到system/app或者priv-app 2.具有系統簽名
重新編譯SystemUI驗證,可以發現功能雖然可以,但是還是存在問題;如果切換語言的話,會導致“清理app的title”變成相應的語言,還是不起作用;那麼在TaskViewHeader.java檔案中檢視是否有獲取App相關資訊函式;是否有任務棧之類的變數呢?仔細檢視程式碼,在該mDismissButton上方的mIconView中有一個Task mTask全域性變數,frameworks\base\packages\SystemUI\src\com\android\systemui\recents\model\Task.java
檢視該類,很明顯的看到該類有一個getComponent()的方法,能夠返回應用的元件名;因此完全可以通過獲取的元件名,再獲得相應的包名既可以完全解決該問題。
如何獲得getComponent()方法呢?該方法是Task中TaskKey的內部類的方法;TaskKey又是Task的公共的全域性變數,那麼可以通過mTask獲取到對應的TaskKey屬性,再由TaskKey呼叫getComponent()就可以完全解決!
修改上述程式碼如下:
ComponentName cn = mTask.key.getComponent();
String pkgName = cn.getPackageName(); //獲取包名
String className = ngetClassName(); //獲取類名
if("清理app的類名".equalsIgnoreCase(pkgName)){
activityManager.forceStopPackage("清理app的類名");
}
其實通過做android系統開發,有些問題主要是考慮到系統是否有類似的功能和對應的函式,這也就要求我們有時對原始碼有個大致的印象,能夠定位到問題點、相應的系統函式或者系統功能,完成自己所需要的功能和問題的解決方案!