- 浏览: 1065974 次
- 性别:
- 来自: 南昌
文章分类
- 全部博客 (276)
- 生活 (1)
- 代码之美 (22)
- Media (7)
- Android Widget (3)
- Android Intent (1)
- Android Activity (4)
- UI event handle--UI事件处理机制 (2)
- Java基础知识 (12)
- android Databases (5)
- Android 系统知识 (70)
- 平常遇到的问题与解决方法 (38)
- Android TextView/EditView (2)
- Thinking Java (1)
- android webkit (6)
- JSON (1)
- XML (4)
- HTTP (1)
- Google Weather API (1)
- android 2.3 NFC (10)
- android app (20)
- android framework (7)
- C++ (2)
- android System (5)
- Pthread (1)
- Wifi (8)
- Unix/Linux C (8)
- Android 4.0 (1)
- Mail (1)
- Smack 源码学习 (4)
- iOS (4)
- Android (1)
- git (1)
- Gallery3d (2)
- React-Natice (1)
最新评论
-
dd18349182956:
你是用的smack哪个版本?我用的smack4.1.3和sma ...
关于socket长连接的心跳包 -
xukaiyin:
全英文
getApplicationContext()与this,getBaseContext() -
裂风矢:
...
<category android:name="android.intent.category.DEFAULT" /> 惹的祸 -
xanthodont:
mark一下
XMPP——Smack -
Evilover3:
mark一下,学习了
XMPP——Smack
在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐仍在后台播放
1.先从UI切入问题分析,使用Monitor—Hierarchy View找到清除任务X按钮对应的id为r.id.dismiss_task,并且属于SystemUI
2.到SystemUI定位到包含dismiss_task的是TaskViewHeader.java,该按钮对应的onClick事件为:
3.查看TaskView.java中的dismissTask
这里EventBus send一个DismissTaskViewEvent,处理完成会回调再发生一个TaskViewDismissedEvent
5.定位到处理DismissTaskViewEvent是在TaskStackView.java
处理TaskViewDismissedEvent
6.接着DeleteTaskDataEvent在RecentsActivity.java处理
7.SystemServicesProxy.java中removeTask
这里就是关键代码了,通过调用ActivityManager的removeTask来删除任务
8.通过ActivityManager.java其对应的是ActivityManagerService.java
9.ActivityStackSupervisor.java
通过上述定位会发现music app包含了前台的服务foregroundServices,所以其process不会被kill掉。这个是google原生设计的。
那解决该问题,我们可以增加判断如果是removeFromRecents 为true时将其包含foregroundServices也kill掉
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掉
发表评论
-
Android Webview加载www.youtube.com的问题
2019-04-25 10:36 990Android Webview加载www.youtube.co ... -
EditText键盘删除字符的原理
2018-10-29 19:21 1246转https://blog.csdn.net/tankai19 ... -
Background execution not allowed
2018-10-22 19:02 357911-05 10:08:18.058 673 736 ... -
failed to set system property
2018-10-17 09:21 4366在App的mk文件设置了LOCAL_CERTIFICATE : ... -
CtsDeqpTestCases fail
2018-07-27 09:44 3015Suite / Plan:VTS / cts-on-gsi ... -
在DocumentUI中的Recent(最近)列表无法显示图片的缩略图
2018-06-12 18:23 938今天客户提了一个bug说在短信添加附件,界面无法显示缩略图。接 ... -
junit.framework.AssertionFailedError: Failed to get achievable frame rates for O
2018-05-25 15:41 2343之前对于CTS测试的失败case接触不多,组长突然转了这样一个 ... -
Android 模拟各种事件的方法
2018-05-17 16:30 1523有时候没有对应的硬件设备,那我们就得通过某种方式来模拟。比如模 ... -
Android Email 新建邮件时一直显示“waiting for sync”
2018-02-28 15:48 989当用户在Setting中清除了Email的data,再返回到E ... -
javax.net.ssl.SSLHandshakeException: Unacceptable certificate: CN=GeoTrust SSL C
2018-01-30 16:48 3771最近从Android N升级到Android O,发现163的 ... -
Email中附件名称中包含中文字符显示乱码
2017-11-28 17:09 1609Email中附件名称中包含中文字符显示乱码是因为附件虽包含了中 ... -
不能再通过createPackageContext来访问另外一个应用的资源(Sharepreference)
2017-11-14 17:22 1462以前我们可以通过createPackageContext来访问 ... -
当Email未设置账户时,通过ACTION_SENDTO启动会报ActivityNotFoundException
2017-09-27 18:15 534当Email未设置账户时,通过ACTION_SENDTO启动会 ... -
java.lang.SecurityException: Permission Denial: reading...requires android.permi
2016-05-12 11:12 2369一直在忙于Gallery,最近遇到了这样的bug,在Setti ... -
android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a read
2015-11-27 14:50 2956android.database.sqlite.SQLiteR ... -
AsyncTask
2015-08-21 17:43 416转自http://blog.csdn.net/hitlion2 ... -
解决IllegalStateException: Can not perform this action after onSaveInstanceState
2015-08-07 18:07 1090转自http://www.cnblogs.com/zgz345 ... -
Android setTag方法的key问题
2015-08-03 19:22 1072转自http://www.cnblogs.com/whitew ... -
ActivityGroup对子Activity的管理
2013-06-27 17:41 2104转自http://eyeandroid.diandian.co ... -
listview在activitygroup切换后无法点击的问题
2013-05-14 10:14 1495转自:http://blog.csdn.net/daguaio ...
相关推荐
Android 11 修改最近任务栏无法kill正在播放的音乐
在Windows操作系统中,托盘区域(也称为系统托盘或通知区域)位于任务栏的右侧,通常用于显示各种应用程序的图标,例如网络连接、音量控制等。这些图标代表正在运行的后台进程,用户可以通过它们快速访问或管理相关...
标题 "不出现在任务栏上的程序.rar" 暗示了我们关注的是计算机操作系统中的一个特定现象,即某些程序在运行时不会在任务栏上显示图标或任务条目。这种情况可能是由于程序的设置、系统配置或者操作系统的问题导致的。...
在Windows操作系统中,任务栏图标闪烁通常是一种通知机制,用于提醒用户有未读的消息或正在进行的后台活动。这种现象在“带有声音播放的任务栏图标闪烁”问题中,可能与多种因素有关,包括软件冲突、系统设置、驱动...
在Windows操作系统中,任务栏是用户界面的重要组成部分,它提供了启动和切换应用程序、查看系统状态以及访问关键功能的快捷方式。然而,有时任务栏可能会遇到各种问题,如无响应、消失或者频繁崩溃,这给用户的日常...
在Windows XP操作系统中,任务栏是用户日常操作中不可或缺的一部分,它承载了启动应用程序、切换窗口、查看系统状态等功能。然而,由于系统更新、软件冲突或病毒感染,任务栏可能会出现各种问题,如任务栏消失、无法...
4. **重置设置**:脚本还可能尝试重置与任务栏相关的用户配置,比如恢复默认的任务栏位置、大小和状态,或者清除可能导致问题的自定义设置。 5. **更新驱动和补丁**:虽然Windows XP已经停止了官方支持,但可能仍有...
在Windows操作系统中,任务栏是用户界面的重要组成部分,它提供了快速访问常用应用程序、切换活动窗口、查看系统状态以及执行各种操作的功能。然而,有时任务栏可能会出现故障,比如不显示Internet Explorer图标,...
4. **自定义设置丢失**:如果你发现任务栏的布局、隐藏状态或功能异常,可以尝试在“任务栏设置”中恢复默认设置。如果脚本能够修复,那么它可能涉及重置这些设置。 5. **系统服务问题**:某些关键服务如“Shell ...
在Windows XP系统中,任务管理器是一个至关重要的工具,它提供了对系统运行状态的全面洞察,包括当前运行的进程、CPU使用率、内存占用、网络活动等信息。本篇文章将深入探讨任务管理器中的所有进程,并讲解如何利用...
在Linux操作系统中,进程管理是一项重要的任务,它涉及到系统性能优化、故障排查等多个方面。本文将详细介绍如何使用`ps`命令来查看系统中的进程以及如何处理僵尸进程。 #### 二、ps命令详解 `ps`命令是最基本也是...
标题中的“win10系统右击任务栏时一直转圈、卡死的修复工具”指出的问题,是Windows 10用户在操作系统中遇到的一个常见故障。通常,当用户尝试右键点击任务栏时,系统应该弹出一个菜单,但在这个情况下,任务栏可能...
在Windows系统中,资源管理器通常指的是Explorer.exe,它负责桌面、任务栏和文件系统的管理。然而,我们今天讨论的重点是"资源管理器中的各进程",这涉及到计算机运行时后台的各个程序和服务。 进程是操作系统中...
在Windows操作系统中,系统托盘区域(也称为通知区域)是位于任务栏右侧的一个区域,通常包含各种程序的图标。这些图标可能是后台运行的应用程序、服务或系统工具的代表。然而,随着时间的推移,由于程序异常退出或...
在Windows 7及更高版本中,任务栏引入了一项创新特性——任务栏进度条,这个功能为用户提供了一个直观的方式,来了解后台进程的执行进度,特别是对于那些没有独立进度窗口的应用程序来说更为实用。"TaskbarManager....
在Windows操作系统中,任务管理器是一项至关重要的工具,它允许用户监控系统性能、查看正在运行的应用程序、进程和服务,以及管理启动项。标题"windows任务管理器无闪屏刷新"指出,我们将探讨如何实现类似任务管理器...
在Windows XP操作系统中,系统托盘(又称为通知区域)位于任务栏的右侧,通常显示各种应用程序的小图标,包括运行中的程序、服务以及系统状态指示器。这些图标为用户提供了一个快速访问和管理程序的方式,但有时可能...
3. 图标:在本场景中,图标是指那些驻留在托盘区的应用程序小图标,它们代表了正在运行的后台进程或服务。 【详细知识点】: 1. **托盘区的作用**:托盘区是操作系统提供的一种界面元素,允许程序在后台运行的同时...
在Windows 2000操作系统中,任务管理器是一个至关重要的工具,它允许用户查看当前系统中运行的程序和进程,以及系统资源的使用情况。然而,对于许多用户来说,理解这些进程的具体功能可能并不直观,尤其是那些由系统...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...