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
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 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 SparseArray if (appProcs != null) { for (int i=0;i procs.add(appProcs.valueAt(i)); } } // Kill the running processes. for (int i=0; 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