Monitoring Activity life cycle methods and case explanations

Get into the habit of writing together! This is the 4th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

This article mainly explains how to quickly implement Activity lifecycle monitoring and its application in official lifecycle, third-party libraries Glide, and PermissionX

1. ActivityLifecycle monitoring

  • FragmentImplement Activitylifecycle monitoring

As we all know, Fragmentthe distribution of the medium life cycle is mainly dependent Activity, so in order to monitor Activitythe life cycle, we can directly add an empty one Fragment:

class TestFragment(): Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
       
    }

    override fun onDestroy() {
        super.onDestroy()
    }
}

//首先要获取activity
activity.supportFragmentManager.beginTransaction().apply {
    add(TestFragment(), "TestFragment").commit()
}
复制代码

In this way, we can monitor the life cycle in the methods such as , and execute the relevant logic onCreate.onDestoryActivity

PS: 通过FragmentManager的FragmentTransaction添加Fragment时,add方法的第二个参数tag不要直接传入TestFragment::class.java.simpleName,因为一旦Fragment发生了混淆,可能会出现多个添加的不同Fragment的tag相同的情况,影响后续使用

  • registerActivityLifecycleCallbacksImplement Activitylifecycle monitoring (api>=29)

This method is mainly provided by SDK>=29, look at the source code:

//回调集合
private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
        new ArrayList<Application.ActivityLifecycleCallbacks>();

//添加监听Activity生命周期的回调
public void registerActivityLifecycleCallbacks(
        @NonNull Application.ActivityLifecycleCallbacks callback) {
    synchronized (mActivityLifecycleCallbacks) {
        mActivityLifecycleCallbacks.add(callback);
    }
}
复制代码

Let's see mActivityLifecycleCallbackswhere it is called. Here is an onStartexample of the life cycle of Activity:

private Object[] collectActivityLifecycleCallbacks() {
    Object[] callbacks = null;
    synchronized (mActivityLifecycleCallbacks) {
        if (mActivityLifecycleCallbacks.size() > 0) {
            callbacks = mActivityLifecycleCallbacks.toArray();
        }
    }
    return callbacks;
}

    private void dispatchActivityStarted() {
        getApplication().dispatchActivityStarted(this);
        //获取mActivityLifecycleCallback回调数组
        Object[] callbacks = collectActivityLifecycleCallbacks();
        if (callbacks != null) {
            for (int i = 0; i < callbacks.length; i++) {
            //分发start生命周期
                ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityStarted(this);
            }
        }
    }


protected void onStart() {
    ...
    //调用dispatchActivityStarted实现生命周期分发
    dispatchActivityStarted();
    ...
}
复制代码

ActivityThe method onStartis called in the dispatchActivityStarted()distribution life cycle, the latter first calls to collectActivityLifecycleCallbacks()get the added life cycle callback collection and converts it into an array, and then traverses the onStartlife cycle of the distribution Activity in turn

2. Case 1: Application practice of the official library lifecycle

The official library is also a life cycle monitoring lifecycleimplemented by the combination of the above two methods :Activity

public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        LifecycleCallbacks.registerIn(activity);
    }
    //兼容旧版本
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        manager.executePendingTransactions();
    }
}


static void registerIn(Activity activity) {
    activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}

复制代码

As you can see from the source code, if SDK >= 29, the registerActivityLifecycleCallbacksmonitoring life cycle is used, and if it is less than 29, it is monitored by adding ReportFragmentit to Activity.

It can be noticed that even if sdk>=29, the added logic will still follow ReportFragment, this is mainly for compatibility with old versions

3. Case 2: Glide library application practice

Glide defines a class named SupportRequestManagerFragment, inherited from Fragment:

public class SupportRequestManagerFragment extends Fragment {
    private final ActivityFragmentLifecycle lifecycle;
    
    @Override
    public void onStart() {
      lifecycle.onStart();
    }

    @Override
    public void onStop() {
      lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
      lifecycle.onDestroy();
    }
}
复制代码

by getSupportRequestManagerFragment()adding toActivity

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    @NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
  SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
  if (current == null) {
    current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = new SupportRequestManagerFragment();
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
    }
  }
  return current;
}
复制代码

As we all know, the withfunction that uses Glide needs to pass in one Context, which can be Activity, Fragmentetc.

The purpose of Glide SupportRequestManagerFragmentis to monitor the life cycle of Fragmentor , when it executes/restores the image loading request, stops the image loading request, and performs some operations of resource release.Activity界面可见界面不可见界面销毁

This is one of Glide's optimization measures for image loading to reduce resource waste

4. Case 3: PermissionX library application practice

This library implements permission application, and permission application must also be inseparable Activity. In order not to invade the logic of the business layer as much as possible, here we cleverly use the addition Fragmentmethod to achieve permission application and callback processing:

class InvisibleFragment : Fragment() {
    private val requestWriteSettingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    //权限申请回调处理
        onRequestWriteSettingsPermissionResult()
    }
    //发起权限申请
    fun requestWriteSettingsPermissionNow(permissionBuilder: PermissionBuilder, chainTask: ChainTask) {
        requestWriteSettingsLauncher.launch(intent)
    }
}
复制代码

The above permission application is written using the Activity ResultAPI. For details, please refer to Guoshen's article.

Add to:

private val invisibleFragment: InvisibleFragment
    get() {
        val existedFragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG)
        return if (existedFragment != null) {
            existedFragment as InvisibleFragment
        } else {
            val invisibleFragment = InvisibleFragment()
            fragmentManager.beginTransaction()
                .add(invisibleFragment, FRAGMENT_TAG)
                .commitNowAllowingStateLoss()
            invisibleFragment
        }
    }
复制代码

The source code is very simple, the principle is exactly the same as the one mentioned at the beginning, you can just take a look.

Guess you like

Origin juejin.im/post/7082962634051420190