1. 程式人生 > >android最近任務列表,刪除某個應用操作

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