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