preface

Alipay’s gesture password can be activated in two ways: the first is activated when entering the app, and the second is activated when entering financial management.

implementation

1. Let’s analyze the first way, which is to activate the gesture password when entering the APP

When entering the APP, start the gesture password, there is a key knowledge point, front and background switch, how to judge the APP has done the front and background switch?

(1) use ProcessLifecycleOmner

ProcessLifecycleOwner

This class provides lifecycle for the entire APP process.

Think of it as a LifecycleOwner for all activities, where Lifecycle.event. ON_START goes into the foreground on behalf of the app and Lifecycle.event. ON_STOP goes into the background on behalf of the app. Lifecycle.Event.On_RESUME and Lifecycle.Event.ON_PAUSE can also represent foreground and background access respectively.

ProcessLifecycleOwner.get().lifecycle.addObserver(object:LifecycleObserver{
 
            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun onForeground(){
                EasyLog.e(TAG,"== onForeground==")
            }
 
            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun onBackground(){
                EasyLog.e(TAG,"== onBackground==")
            }
 
 
        });
Copy the code

ProcessLifecycle does a great job of listening for front and background switching but is not very good for gesture password switching. First of all, the home and login pages don’t need to pop up gesture passwords, these pages need to be filtered and ProcessLifecycle doesn’t do that very well. Now let’s look at the second method.

LifecycleCallbacks:

So using this interface, we’re going to count the number of times we start the onActivityStart callback mActivityCount++, In the onActivityStop callback, mActivityCount– is considered foreground when mActivityCount == 1 and background when mActivityCount ==0. The code is as follows:

Class GestureLifecycleHandler constructor(context: context): / / Class GestureLifecycleHandler constructor Application.ActivityLifecycleCallbacks { companion object{ private const val TAG = "GestureLifecycleHandler" } private Val uiScope = CoroutineScope(dispatchers.main) private var isOpenHandLock = false init { private var mActivityCount: Int = 0 override fun onActivityPaused(activity: Activity?) { } override fun onActivityResumed(activity: Activity?) { } override fun onActivityStarted(activity: Activity?) { if(activityFilter(activity)){ return } mActivityCount ++ EasyLog.e(TAG,"onForeground = $mActivityCount") uiScope.launch { withContext(Dispatchers.IO){ isOpenHandLock = GestureManager.getAppGestureState() if(isOpenHandLock && mActivityCount == 1){ GestureActivity.actionStart(activity!! ,GestureActivity.GestureState.Verify) } } } } override fun onActivityDestroyed(activity: Activity?) { } override fun onActivitySaveInstanceState(activity: Activity? , outState: Bundle?) { } override fun onActivityStopped(activity: Activity?) { if(activityFilter(activity)){ return } mActivityCount-- EasyLog.e(TAG,"onBackground = $mActivityCount") } override fun  onActivityCreated(activity: Activity? , savedInstanceState: Bundle?) { } private fun activityFilter(activity: Activity?) :Boolean{ return activity is SplashActivity } }Copy the code

2. We analyze the second way: the gesture password pops up when entering financial management

You can use ProcessLifecycleOwner to listen for changes in both the front and the back of the wealth fragment.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ProcessLifecycleOwner.get().lifecycle.addObserver(GestureLife(this))
    }
Copy the code
private const val TAG = "GestureLife"
 
 open class GestureLife(val fragment: GestureLockFragment) :LifecycleObserver{
 
 
     private val uiScope  =  CoroutineScope(Dispatchers.Main)
 
 
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onVisible() {
       EasyLog.e(TAG,"==ON_RESUME==")
        if(fragment.isHidden){
            EasyLog.e(TAG,"等待台跳出手势密码")
            fragment.waitingGesture = true
 
        }
        if(!fragment.isHidden||fragment.isVisible){
            EasyLog.e(TAG,"==isVisible==")
            uiScope.launch {
                withContext(Dispatchers.IO){
                    val  isOpenHandLock =  GestureManager.getFragmentGestureState()
                    if(isOpenHandLock  && !GestureLockFragment.showGesture){
                          GestureLockFragment.showGesture = true
                          GestureActivity.actionStart(ActivityUtils.getTopActivity(),GestureActivity.GestureState.Verify)
                    }
                }
 
            }
        }
 
 
    }
     @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
     fun onBackground(){
         EasyLog.e(TAG,"==onBackground==")
         GestureLockFragment.showGesture = false
     }
 
}
Copy the code

After the fragment is switched between front and back, the fragment is visible, so it will pop up directly after a long time. If it is not visible, it will pop up again when it is visible, so it needs to deal with onHidden.

override fun onHiddenChanged(hidden: Boolean) { super.onHiddenChanged(hidden) EasyLog.e(TAG,"onHiddenChanged") if(! hidden){ if(waitingGesture && ! showGesture){ waitingGesture = false showGesture = true GestureActivity.actionStart(activity!! , GestureActivity.GestureState.Verify) } } }Copy the code

Source: [github.com/ThirdPrince…].