android最近任務列表,刪除某個應用操作
1、SystemUI工程
RecentsActivity.java
protected void onCreate(BundlesavedInstanceState) {
getWindow().addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR);
setContentView(R.layout.status_bar_recent_panel);
mRecentsPanel = (RecentsPanelView)findViewById(R.id.recents_root);
在SwipeHelper.java中,onTouch回撥中,處理介面的touch事件,最後會呼叫到RecentsPanelView中的handleSwipe,刷掉對應的apk
RecentsPanelView.java
public void handleSwipe(View view) {
TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription;
if (ad == null) {
Log.v(TAG, "Not able to find activity description for swiped task;view=" + view + " tag=" + view.getTag());
return;
}
if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel());
=》這裡的日誌挺有意思的
mRecentTaskDescriptions.remove(ad);
mRecentTasksLoader.remove(ad);
// Handled by widget containers to enable LayoutTransitions properly mListAdapter.notifyDataSetChanged();
if (mRecentTaskDescriptions.size() == 0) {
dismissAndGoBack();
}
// Currently, either direction means the same thing, so ignore direction andremove the task.
final ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
am.removeTask(ad.persistentTaskId,ActivityManager.REMOVE_TASK_KILL_PROCESS); =》呼叫AMS服務提供的介面removeTask,殺程序,注意flag
// Accessibility feedback
setContentDescription(getContext().getString(R.string.accessibility_recents_item_dismissed,ad.getLabel()));
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
setContentDescription(null);
}
}
2、framework層的ActivityManagerService.java
public boolean removeTask(inttaskId, int flags) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,"removeTask()");
long ident = Binder.clearCallingIdentity();
try {
ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1); =》1、UI:刪除task棧中該apk的activity
if (r != null) {
mRecentTasks.remove(r.task);
cleanUpRemovedTaskLocked(r,(flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0); =》殺程序,注意前面傳入的flag
return true;
} else {
TaskRecord tr = null;
int i=0;
while (i < mRecentTasks.size()) {
TaskRecord t = mRecentTasks.get(i);
if (t.taskId == taskId) {
tr = t;
break;
}
i++;
}
if (tr != null) {
if (tr.numActivities <= 0) {
//Caller is just removing a recent task that is not actively running. That is easy!
mRecentTasks.remove(i);
} else {
Slog.w(TAG, "removeTask: task " + taskId + " does not have activities to remove, " + " but numActivities=" + tr.numActivities + ": " + tr);
}
}
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
return false;
}
private void cleanUpRemovedTaskLocked(ActivityRecordroot, boolean killProcesses) {
TaskRecord tr = root.task;
Intent baseIntent = new Intent(tr.intent != null ? tr.intent :tr.affinityIntent);
ComponentName component = baseIntent.getComponent();
if (component == null) {
Slog.w(TAG, "Now component for baseintent of task: " + tr);
return;
}
// Find any running services associated with this app.
ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
for (ServiceRecord sr : mServices.values()) {
if (sr.packageName.equals(component.getPackageName())) {
services.add(sr);
}
}
// Take care of any running services associated with the app.
for (int i=0; i<services.size(); i++) {
ServiceRecord sr = services.get(i);
if (sr.startRequested) {
if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Slog.i(TAG, "Stopping service " + sr.shortName + ": removetask");
stopServiceLocked(sr); =》2、停止apk啟動的service
} else {
sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,sr.makeNextStartId(), baseIntent, -1));
if(sr.app != null && sr.app.thread != null) {
sendServiceArgsLocked(sr, false);
}
}
}
}
if (killProcesses) {
// Find any running processes associated with this app.
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
SparseArray<ProcessRecord> appProcs =mProcessNames.getMap().get(component.getPackageName());
if (appProcs != null) {
for (int i=0;i<appProcs.size(); i++) {
procs.add(appProcs.valueAt(i));
}
}
// Kill the running processes.
for (int i=0; i<procs.size(); i++) {
ProcessRecord pr = procs.get(i);
if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Slog.i(TAG, "Killing " + pr.toShortString() + ": removetask");
EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid, pr.processName, pr.setAdj,"remove task");
Process.killProcessQuiet(pr.pid); =》3、殺apk程序,這裡用的是killProcessQuiet
} else {
pr.waitingToKill = "remove task";
}
}
}
}
如果是系統應用(/system/app/),這種方式殺死後,好像會被重新拉起;
(建立程序是會註冊AppDeathRecipient)
原始碼參考地址:
http://androidxref.com