RecentsActivity 응답은 이벤트의 과정을 죽일 것입니다 방법

2019년 11월 30일

키워드 : 최근 응용 프로그램 목록, SystemUI, 안드로이드 응용 프로그램 이벤트 인터셉터 죽이기


안드로이드 시스템은 '최근 사용한 앱 목록 "기능은 현재 표시 백그라운드에서 실행 나중에 응용 프로그램이나 프로세스에서 트리거 실행되고 있습니다. 사용자는 즉시 또한 응용 프로그램 프로세스를 죽일 수있는이 목록에 응용 프로그램을 전환 할 수 있습니다.

 

오늘은 수요를 충족 : 죽이고, 응용 프로그램 화이트리스트는 수 "최근 응용 프로그램 목록"되지 않습니다 응용 프로그램 "화이트리스트"기능을 추가 할 수 있습니다.

 

즉, 차단 응용 프로그램 이벤트를 죽인다.

 

이 기능은 SystemUI APK의 최근 응용 프로그램의 목록입니다. APK는 복잡 할 수 나는 '최근 사용한 앱 목록, "작은 기회, 그리고 궁극적으로이 응용 프로그램 허용 목록을 터치 간주 몇 시간을 보냈다.

 

포인트는 현재 레코드의 필요성을 알게 될 것이다, 우리는 도움에 다른 학생들이 같은 요구 사항이 있기를 바랍니다.

 

또한 저자는 달성하기위한 실행 수요 Android5.1 운영 체제 rk3288 개발 보드에 언급.

 

먼저, 다음과 같이 핵심 아키텍처 다이어그램의 최근 응용 프로그램 목록 :

SystemUI APK는 RecentsActivity 두 세트를 갖고있는 것 같아요. 우리는 걱정 할 필요가 com.android.systemui.recents의 패키지에서.

 

모든 RecentsView보기 제어를 시작하는부터.

 

기록 TaskView 각 애플리케이션 프로세스에 대응이 아래와 같이 :

TaskStackView의 수는 공통 RecentsView 레이아웃에로드하고있는 동안은, TaskStackView에 TaskView의 수를 포함합니다.

 

이유는 여러 TaskStackView이 있나요? 최근 안드로이드 응용 프로그램 프로세스가 할 기록 될 것이기 때문이다 "캐시." 이것은 당신이 최근에 적용된 녹화가 기록 데이터가 마지막으로 종료하기 전에 찾을 수있는 시스템을 다시 부팅 한 후, 레코드가 캐시됩니다 모든 응용 프로그램에서 사용할보기를 클릭 것입니다. 조금 어려운이 간단한은 우리가 그것을 우리의 더 TaskStackView이 잘 도청에 영향을주지 않습니다 기억으로 명확하게 표현.

 

코드를 변경하는 진행할 수 있기 때문에 음, 우리는 앞의 기본적인 이해를 가지고있다.

 

메인 이벤트 절편 두 가지가 있습니다에 우리는해야합니다

1、点击记录卡片右上角的关闭按钮事件;

2、滑动记录卡片事件;

其中滑动事件又可分为“左右滑动事件”与“上下滑动事件”。显然我们只能拦截“左右滑动”事件。

 

首先,我们要如何来区分哪个卡片是哪个应用呢?这些卡片默认是不记录与它相关的应用进程信息的。

./SystemUI/src/com/android/systemui/recents/views/TaskStackView.java

在 boolean synchronizeStackViewsWithModel() 方法中。

这个方法比较长,但判断卡片与进程信息的关系的代码可不能随便加,笔者将完整代码贴出来:

 1     boolean synchronizeStackViewsWithModel() {
 2         if (mStackViewsDirty) {
 3             RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
 4             SystemServicesProxy ssp = loader.getSystemServicesProxy();
 5 
 6             // Get all the task transforms
 7             ArrayList<Task> tasks = mStack.getTasks();
 8             float stackScroll = mStackScroller.getStackScroll();
 9             int[] visibleRange = mTmpVisibleRange;
10             boolean isValidVisibleRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
11                     stackScroll, visibleRange, false);
12             if (mDebugOverlay != null) {
13                 mDebugOverlay.setText("vis[" + visibleRange[1] + "-" + visibleRange[0] + "]");
14             }
15 
16             // Return all the invisible children to the pool
17             mTmpTaskViewMap.clear();
18             int childCount = getChildCount();
19             for (int i = childCount - 1; i >= 0; i--) {
20                 TaskView tv = (TaskView) getChildAt(i);
21                 Task task = tv.getTask();
22                 int taskIndex = mStack.indexOfTask(task);
23                 if (visibleRange[1] <= taskIndex && taskIndex <= visibleRange[0]) {
24                     mTmpTaskViewMap.put(task, tv);
25                 } else {
26                     mViewPool.returnViewToPool(tv);
27                 }
28             }
29 
30             // Pick up all the newly visible children and update all the existing children
31             for (int i = visibleRange[0]; isValidVisibleRange && i >= visibleRange[1]; i--) {
32                 Task task = tasks.get(i);
33                 TaskViewTransform transform = mCurrentTaskTransforms.get(i);
34                 TaskView tv = mTmpTaskViewMap.get(task);
35                 int taskIndex = mStack.indexOfTask(task);
36 
37                 if (tv == null) {
38                     tv = mViewPool.pickUpViewFromPool(task, task);
39 
40                     if (mStackViewsAnimationDuration > 0) {
41                         // For items in the list, put them in start animating them from the
42                         // approriate ends of the list where they are expected to appear
43                         if (Float.compare(transform.p, 0f) <= 0) {
44                             mLayoutAlgorithm.getStackTransform(0f, 0f, mTmpTransform, null);
45                         } else {
46                             mLayoutAlgorithm.getStackTransform(1f, 0f, mTmpTransform, null);
47                         }
48                         tv.updateViewPropertiesToTaskTransform(mTmpTransform, 0);
49                     }
50                 }
51                 
52                 try {
53                     tv.setTag(null);
54                     String pkg = task.key.baseIntent.getComponent().getPackageName();
55                     for(String pkg2 : RecentsActivity.whiteList) {
56                         if(pkg2.equals(pkg)) {
57                             tv.setTag(false);
58                             break;
59                         }
60                     }
61                 }catch(Exception e) {
62                     e.printStackTrace();
63                 }
64 
65                 // Animate the task into place
66                 tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
67                         mStackViewsAnimationDuration, mRequestUpdateClippingListener);
68 
69                 // Request accessibility focus on the next view if we removed the task
70                 // that previously held accessibility focus
71                 childCount = getChildCount();
72                 if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
73                     TaskView atv = (TaskView) getChildAt(childCount - 1);
74                     int indexOfTask = mStack.indexOfTask(atv.getTask());
75                     if (mPrevAccessibilityFocusedIndex != indexOfTask) {
76                         tv.requestAccessibilityFocus();
77                         mPrevAccessibilityFocusedIndex = indexOfTask;
78                     }
79                 }
80             }
81 
82             // Reset the request-synchronize params
83             mStackViewsAnimationDuration = 0;
84             mStackViewsDirty = false;
85             mStackViewsClipDirty = true;
86             return true;
87         }
88         return false;
89     }

上述代码第 52 行 ~ 第 63 行就是笔者用来判断关系的代码。需要强调的是:只能在那代码代码或它之后去判断。因为在这之前,卡片视图有可能还未实例化。

 

至于要如何记录卡片代表的进程信息,你们自由发挥即可。笔者这里是直接利用卡片View的 setTag() 方法。笔者直接将不能被杀掉的应用的卡片上保存一个 boolean 实例,可以杀的应用则是放空。这样待到后续通过点击卡片右上角的关闭按钮或者左右滑动时只需要简单地判断卡片视图的 getTag() 是否为空就行了。

 

点击右上角的关闭按钮的事件在哪呢?

./SystemUI/src/com/android/systemui/recents/views/TaskView.java

就在这个代码的 onClick() 方法中:

 

在上图红框处的代码就是笔者的拦截代码,只要不让它执行 dismissTask() 就不会杀掉这个进程。

 

滑动事件的流程要稍微复杂一点,但这里只讲核心部分:

./SystemUI/src/com/android/systemui/recents/views/SwiperHelper.java

在这个代码的 onTouchEvent() 方法中:

 

上图红框处是笔者的拦截处理代码。只要不让它执行红框代码后面的语句,应用记录卡片就不会左右方向滑动。

 


 

추천

출처www.cnblogs.com/chorm590/p/11962774.html