超实用的Application.ActivityLifecycleCallbacks 实现第一次启动、冷启动、热启动、切换后台以及返回前台功能

Application.ActivityLifecycleCallbacks 实现第一次启动、冷启动、热启动、切换后台以及返回前台功能

以下是一个使用 AppLifecycleCallbacks 实现上述功能的示例代码:

import android.app.Application;
import android.os.Bundle;

/**
*
* Description: [ActivityLifecycleCallbacks监听相关首次、冷、热启动、前后台等]
*
*/
public class MyAppLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

    private static final String TAG = AppLifecycleCallbacks.class.getSimpleName();

    /**
     * 只对特定包名下的Activity生效
     */
    private static final String PACKAGE_NAME = "com.xxx.cn"; // 替换为您的包名
    private Set<Activity> activitySet = new HashSet<>();


    /**
     * 首次启动严格来说隶属于冷启动,这里之所以单独拎出来,是因为首次启动一般来讲会比非首次启动要久一些,
     * 因为首次启动会做一些系统的初始化工作,当然可以把这些初始化工作可以放在IntentService中执行,所以首次启动速度非常重要。
     */
    private long firstStartDuration; // 记录首次动时长

    /**
     * 定义:启动应用时,后台没有该进程,系统会重新创建一个新的进程给该应用。
     * <p>
     * 首先创建和初始化Application,然后创建和初始化WelcomeActivity,最后显示在界面上。
     */
    private long coldStartTime; // 记录冷启动时间
    private long coldStartDuration;
    /**
     * 2、热启动
     * <p>
     * 定义:从已有的进程启动应用,叫热启动。启动应用时,
     * 后台有该应用的进程(比如按下home键、back键,应用虽然退出,但是该应用的进程会保存在后台);
     * <p>
     * 热启动因为是从已有的进程中启动,所以不会执行 Application,而是直接执行MainActivity的逻辑,
     * 热启动不用创建和初始化Application,因为一个应用从进程的创建到销毁,Application只会初始化一次;
     */
    private long hotStartTime = 0;  // 记录热启动时间
    private long hotStartDuration;
    private int activityCount = 0;

    private int account = 0;
    /**
     * true--后台; false--前台
     */
    private boolean isRunInBackground = false;

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        LogUtils.logd(TAG, "========================= 当前的onActivityCreated:" + activity.getClass().getSimpleName());

        if (isActivityFromSpecificPackage(activity)) {
            activitySet.add(activity);
            activityCount++;
            if (activityCount == 1) { // 应用从后台进入前台,记录启动时间
                coldStartTime = System.currentTimeMillis();
            }
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if (isActivityFromSpecificPackage(activity)) {
            account++;

            LogUtils.logd(TAG + "===== " + activity.getIntent().getFlags() + "==========isTaskRoot=======" + activity.isTaskRoot());

            if (isRunInBackground && !activity.isTaskRoot()) {
                // 后台到前台,在此进行相应操作
                setAppIsRunInBackground(activity, false);
                LogUtils.logd(TAG + "========================= 当前的Activity: 后台》》》前台,在此进行相应操作 " + activity.getClass().getSimpleName());

            }

            if (1 == account) { // 首次或切换到桌面或其他应用或熄屏等情况,再次返回打开APP时
                hotStartTime = System.currentTimeMillis();
                LogUtils.logd(TAG + "========================= 当前的Activity 检查是否是热启动: 后台》》》前台,在此进行相应操作 " + activity.getClass().getSimpleName());
            }
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {
        if (isActivityFromSpecificPackage(activity)) {
            long duration = System.currentTimeMillis();
            if (1 == activityCount) {
                if (null != activity && activity instanceof SplashActivity) {// 冷启动初始化Application,然后创建和初始化WelcomeActivity,最后显示在界面上

                    boolean isFirstUseAppStartFlag = ((SplashActivity) activity).isFirstUseAppStartFlag();

                    if (isFirstUseAppStartFlag) {
                        setAppFirstStartDuration(activity, coldStartTime, duration);
                    }
                    setAppColdStartDuration(activity, coldStartTime, duration);
                } else if (1 == account) {
                    setAppHotStartDuration(activity, hotStartTime, duration);
                }
            }
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
        if (isActivityFromSpecificPackage(activity)) {
            activitySet.remove(activity);
            account--;
            if (account == 0) {
                // 前台到后台,在此进行相应操作
                setAppIsRunInBackground(activity, true);
                LogUtils.logd(TAG + "========================= 当前的Activity: 前台》》》后台,在此进行相应操作 " + activity.getClass().getSimpleName());
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if (isActivityFromSpecificPackage(activity)) {
            activitySet.remove(activity);
            activityCount--;
            if (activityCount < 1 && isRunInBackground) {
                setAppExistMark(activity, true);
                LogUtils.logd(TAG + "========================= 当前正常点击退出APP");
            }
        }
    }

    /**
     * 设置首次启动时长
     *
     * @param activity
     * @param startTime
     * @param endTime
     */
    public void setAppFirstStartDuration(Activity activity, long startTime, long endTime) {
        firstStartDuration = endTime - startTime;
//        LogUtils.logd(TAG, "========first start time: " + firstStartDuration + "ms");
    }

    /**
     * 设置冷启动时长
     *
     * @param activity  必须是 activity instanceof WelcomeActivity
     * @param startTime
     * @param endTime
     */
    public void setAppColdStartDuration(Activity activity, long startTime, long endTime) {
        coldStartDuration = endTime - startTime;
//        LogUtils.logd(TAG, "========Cold start time: " + coldStartDuration + "ms");
    }

    /**
     * 设置热启动时长
     *
     * @param activity
     * @param startTime
     * @param endTime
     */
    public void setAppHotStartDuration(Activity activity, long startTime, long endTime) {
        hotStartDuration = endTime - startTime;
//        LogUtils.logd(TAG, "========holt start time: " + hotStartDuration + "ms");
    }

    /**
     * 设置前台后台
     *
     * @param flag true--后台; false--前台
     * @return true--后台; false--前台
     */
    public boolean setAppIsRunInBackground(Activity activity, boolean flag) {
        isRunInBackground = flag;
        return flag;
    }

    /**
     * 退出App  正常点击退出; 但是kill时是无法监听的
     * @param activity
     * @param flag
     * @return
     */
    public boolean setAppExistMark(Activity activity, boolean flag) {
        isRunInBackground = flag;
        return flag;
    }


    /**
     * isActivityFromSpecificPackage方法用于检查传入的Activity是否属于指定的包名。
     * 如果是,则将该Activity添加到activitySet集合中,并在其生命周期回调事件中执行相应的逻辑。
     * 如果不是,则不执行任何操作。
     * @param activity
     * @return
     */
    private boolean isActivityFromSpecificPackage(@NonNull Activity activity) {
        Intent componentName = new Intent(activity, activity.getClass());
        PackageManager packageManager = activity.getPackageManager();
        ResolveInfo resolveInfo = packageManager.resolveActivity(componentName, 0);
        if (resolveInfo != null && resolveInfo.activityInfo.packageName.equals(PACKAGE_NAME)) {
            return true;
        }
        return false;
    }
}

在上述代码中:

  • 通过一个布尔值 isFirstLaunch 来标识是否是第一次启动。
  • 记录活动上次处于前台的时间,通过与当前时间的比较来判断是冷启动还是热启动。

在实际应用中,您可以根据具体的需求在相应的回调方法中添加更多的逻辑,比如记录日志、进行性能统计、处理资源释放等操作。例如,如果是冷启动,您可能需要进行一些初始化操作,而热启动则可以跳过一些已经完成的初始化步骤以提高启动速度。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值