I. event realization principle:
① View set AccessibilityDelegate
② when the View generates click, long click and other events, it will respond to the original Listener method
③ after the response of the original Listener method is completed, forward the message to the AccessibilityDelegate in the sendAccessibilityEvent method
④ handle the event in sendAccessibilityEvent of AccessibilityDelegate
⑤ do not call the method at the beginning of the call, such as callOnClick, because the event cannot be sent to sendAccessibilityEvent
The following methods can be used
public boolean performClick() { final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); notifyEnterOrExitForAutoFillIfNeeded(true); return result; }
⑥. sendAccessibilityEvent generates the key and value of the event
public void sendAccessibilityEvent(View host, int eventType) { host.sendAccessibilityEventInternal(eventType); }
II. Embedded point of Android component life cycle
① Activity life cycle
We can monitor Activity through Application.ActivityLifecycleCallbacks
② Service & broadcastreceiver life cycle
At present, it can only be implemented manually. As for the implementation method, you can modify the following code
public class ActivityStatusManager implements Application.ActivityLifecycleCallbacks{ public final Integer STATUS_CREATED = 0x0001; public final Integer STATUS_RESUMED = 0x0002; public final Integer STATUS_PAUSED = 0x0003; public final Integer STATUS_STARTED = 0x0004; public final Integer STATUS_STOPED = 0x0005; public final Integer STATUS_DESTROYED = -1; private Map<Activity,Integer> activityStack; public void registerActivityLifecycleCallbacks(Application application) { application.registerActivityLifecycleCallbacks(this); } public void unregisterActivityLifecycleCallbacks(Application application){ application.unregisterActivityLifecycleCallbacks(this); } private static class Holder{ public final static ActivityStatusManager instance = new ActivityStatusManager(); } public static ActivityStatusManager shareInstance(){ return Holder.instance; } private ActivityStatusManager(){ activityStack = new ArrayMap<Activity,Integer>(); } public Integer getActivityStatus(Activity activity) { final Integer status = activityStack.get(activity); if(status==null){ return STATUS_DESTROYED; } return status; } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { if(activity!=null){ activityStack.put(activity,STATUS_CREATED); } } @Override public void onActivityStarted(Activity activity) { if(activity!=null){ activityStack.put(activity,STATUS_STARTED); } } @Override public void onActivityResumed(Activity activity) { if(activity!=null){ activityStack.put(activity,STATUS_RESUMED); } } @Override public void onActivityPaused(Activity activity) { if(activity!=null){ activityStack.put(activity,STATUS_PAUSED); } } @Override public void onActivityStopped(Activity activity) { if(activity!=null){ activityStack.put(activity,STATUS_STOPED); } synchronized (Holder.instance){ int counter = 0; for (Map.Entry<Activity,Integer> entry : activityStack.entrySet()){ if(entry.getValue()==STATUS_STOPED){ counter++; } } if(counter>0 && activityStack.size()==counter){ BaseApplication.setInForeground(false); }else{ BaseApplication.setInForeground(true); } } } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { Application application = activity.getApplication(); activityStack.remove(activity); clearInvalidActivity(); if(activityStack.isEmpty() && application!=null){ unregisterActivityLifecycleCallbacks(application); } } public void clearInvalidActivity(){ Iterator<Map.Entry<Activity,Integer>> iterator = activityStack.entrySet().iterator(); do{ if(!iterator.hasNext()) return; Map.Entry<Activity, Integer> entry = iterator.next(); if(entry!=null && activityIsDestroyed(entry.getKey()) ){ iterator.remove(); } }while(iterator.hasNext()); } public void finishAll(){ if(activityStack.isEmpty()) return; Activity activity = null; Iterator<Map.Entry<Activity,Integer>> iterator = activityStack.entrySet().iterator(); do{ if(!iterator.hasNext()) return; Map.Entry<Activity, Integer> entry = iterator.next(); if(entry!=null ){ activity = entry.getKey(); if(activity!=null && !activityIsDestroyed(activity)) { activity.finish(); } iterator.remove(); } }while(iterator.hasNext()); } /** * Whether the program runs in the foreground * * @return */ public boolean isForegroundProcess(Context context) { // Returns a list of application processes that are running on the // device ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); String packageName = context.getApplicationContext().getPackageName(); List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager .getRunningAppProcesses(); if (appProcesses == null) return false; for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { // The name of the process that this object is associated with. if (appProcess.processName.equals(packageName) && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return true; } } return false; } private boolean activityIsDestroyed(Activity thatActivity){ if(thatActivity==null) return true; if(Build.VERSION.SDK_INT>=17){ return thatActivity.isDestroyed() || thatActivity.isFinishing(); }else{ return thatActivity.isFinishing(); } } }
III. environmental burying points
Register ComponentCallbacks2 in Application