MyException - 我的188bet网
当前位置:我的188bet网» 移动开发 » 在任务栏中清除掉播放器的历程,状态栏仍有音乐播放

在任务栏中清除掉播放器的历程,状态栏仍有音乐播放器状态,且音乐仍在后台播放

www.x8vin4.com  网友分享于:2018-06-06  浏览:0次
在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐仍在后台播放
在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐仍在后台播放

1.先从UI切入问题分析,使用Monitor—Hierarchy View找到清除任务X按钮对应的id为r.id.dismiss_task,并且属于SystemUI

2.到SystemUI定位到包含dismiss_task的是TaskViewHeader.java,该按钮对应的onClick事件为:
TaskView tv = Utilities.findParent(this, TaskView.class);
            tv.dismissTask();

            // Keep track of deletions by the dismiss button
            MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
                    Constants.Metrics.DismissSourceHeaderButton);


3.查看TaskView.java中的dismissTask
void dismissTask() {
        // Animate out the view and call the callback
        final TaskView tv = this;
        DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv);
        dismissEvent.addPostAnimationCallback(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv,
                        new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
                                Interpolators.FAST_OUT_SLOW_IN)));
            }
        });
        EventBus.getDefault().send(dismissEvent);
    }

这里EventBus send一个DismissTaskViewEvent,处理完成会回调再发生一个TaskViewDismissedEvent

5.定位到处理DismissTaskViewEvent是在TaskStackView.java
    public final void onBusEvent(DismissTaskViewEvent event) {
        // For visible children, defer removing the task until after the animation
        mAnimationHelper.startDeleteTaskAnimation(
                event.taskView, useGridLayout(), event.getAnimationTrigger());
    }


处理TaskViewDismissedEvent
public final void onBusEvent(TaskViewDismissedEvent event) {
        // Announce for accessibility
        announceForAccessibility(getContext().getString(
                R.string.accessibility_recents_item_dismissed, event.task.title));

        if (useGridLayout() && event.animation != null) {
            event.animation.setListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animator) {
                    if (mTaskViewFocusFrame != null) {
                        // Resize the grid layout task view focus frame
                        mTaskViewFocusFrame.resize();
                    }
                }
            });
        }

        // Remove the task from the stack
        mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
        EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
        if (mStack.getTaskCount() > 0 && Recents.getConfiguration().isLowRamDevice) {
            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
        }

        MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
                event.task.key.getComponent().toString());
    }


6.接着DeleteTaskDataEvent在RecentsActivity.java处理

public final void onBusEvent(DeleteTaskDataEvent event) {
        // Remove any stored data from the loader
        RecentsTaskLoader loader = Recents.getTaskLoader();
        loader.deleteTaskData(event.task, false);

        // Remove the task from activity manager
        SystemServicesProxy ssp = Recents.getSystemServices();
        ssp.removeTask(event.task.key.id);
    }


7.SystemServicesProxy.java中removeTask
 /** Removes the task */
    public void removeTask(final int taskId) {
        if (mAm == null) return;
        if (RecentsDebugFlags.Static.EnableMockTasks) return;

        // Remove the task.
        mUiOffloadThread.submit(() -> {
            mAm.removeTask(taskId);
        });
    }

这里就是关键代码了,通过调用ActivityManager的removeTask来删除任务

8.通过ActivityManager.java其对应的是ActivityManagerService.java
    @Override
    public boolean removeTask(int taskId) {
        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
    }


9.ActivityStackSupervisor.java
    boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
            boolean pauseImmediately) {
        final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
                INVALID_STACK_ID);
        if (tr != null) {
            tr.removeTaskActivitiesLocked(pauseImmediately);
            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
            if (tr.isPersistable) {
                mService.notifyTaskPersisterLocked(null, true);
            }
            return true;
        }
        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
        return false;
    }


 void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents) {
        if (removeFromRecents) {
            mRecentTasks.remove(tr);
            tr.removedFromRecents();
        }
        ComponentName component = tr.getBaseIntent().getComponent();
        if (component == null) {
            Slog.w(TAG, "No component for base intent of task: " + tr);
            return;
        }

        // Find any running services associated with this app and stop if needed.
        mService.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));

        if (!killProcess) {
            return;
        }

        // Determine if the process(es) for this task should be killed.
        final String pkg = component.getPackageName();
        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mProcessNames.getMap();
        for (int i = 0; i < pmap.size(); i++) {

            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
            for (int j = 0; j < uids.size(); j++) {
                ProcessRecord proc = uids.valueAt(j);
                if (proc.userId != tr.userId) {
                    // Don't kill process for a different user.
                    continue;
                }
                if (proc == mService.mHomeProcess) {
                    // Don't kill the home process along with tasks from the same package.
                    continue;
                }
                if (!proc.pkgList.containsKey(pkg)) {
                    // Don't kill process that is not associated with this task.
                    continue;
                }

                for (int k = 0; k < proc.activities.size(); k++) {
                    TaskRecord otherTask = proc.activities.get(k).getTask();
                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
                        // Don't kill process(es) that has an activity in a different task that is
                        // also in recents.
                        return;
                    }
                }

                if (proc.foregroundServices) {
                    // Don't kill process(es) with foreground service.
                    return;
                }

                // Add process to kill list.
                procsToKill.add(proc);
            }
        }

        // Kill the running processes.
        for (int i = 0; i < procsToKill.size(); i++) {
            ProcessRecord pr = procsToKill.get(i);
            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                    && pr.curReceivers.isEmpty()) {
                pr.kill("remove task", true);
            } else {
                // We delay killing processes that are not in the background or running a receiver.
                pr.waitingToKill = "remove task";
            }
        }
    }

通过上述定位会发现music app包含了前台的服务foregroundServices,所以其process不会被kill掉。这个是google原生设计的。
那解决该问题,我们可以增加判断如果是removeFromRecents 为true时将其包含foregroundServices也kill掉
m88 188bet uedbet 威廉希尔 明升 bwin 明升88 bodog bwin 明升m88.com 18luck 188bet unibet unibet Ladbrokes Ladbrokes casino m88明升 明升 明升 m88.com 188bet m88 明陞 uedbet赫塔菲官网 365bet官网 m88 help

文章评论

软件开发程序错误188betExceptionCopyright © 2009-2015 MyException 版权所有