Android判断前后台的方法分析(二)

( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)🥬( ´◔︎ ‸◔︎)

判断前后台的方法往往五花八门,这次让我们再一起看一种Android中常用的前后台切换的方法 ActivityLifecycleCallbacks。

ActivityLifecycleCallbacks是一个接口,它可以用来监听Activity的生命周期事件。当应用程序中的Activity经历生命周期事件时,系统会回调这个接口中的相应方法,从而允许开发者在Activity生命周期不同阶段插入自己的逻辑。

详细代码可以看Activity中onCreate方法dispatchActivityCreated,(其实看其他生命周期回调也是一样的)

less 复制代码
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ...不重要的代码省略了...
    dispatchActivityCreated(savedInstanceState);
    ...不重要的代码省略了...
}

再来往里看dispatchActivityCreated到底做了什么

less 复制代码
private void dispatchActivityCreated(@Nullable Bundle savedInstanceState) {
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    Object[] callbacks = collectActivityLifecycleCallbacks();
    if (callbacks != null) {
        for (int i = 0; i < callbacks.length; i++) {
            ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityCreated(this,
                    savedInstanceState);
        }
    }
}
ini 复制代码
private Object[] collectActivityLifecycleCallbacks() {
    Object[] callbacks = null;
    synchronized (mActivityLifecycleCallbacks) {
        if (mActivityLifecycleCallbacks.size() > 0) {
            callbacks = mActivityLifecycleCallbacks.toArray();
        }
    }
    return callbacks;
}

这里的mActivityLifecycleCallbacks就是我们注册进来的生命周期的监听回调

arduino 复制代码
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks()

因此可以看出来,ActivityLifecycleCallbacks的核心逻辑是在应用程序的每一个Activity的生命周期内提供了一个挂钩(hook),允许开发者在特定的时机执行特定的操作,比如在Activity启动时记录日志、在Activity销毁时释放资源等。通过实现ActivityLifecycleCallbacks接口,开发者可以监听应用程序中所有Activity的生命周期事件,从而更好地管理和优化应用程序的性能和行为。

讲了这么多,来点干货,如果想封装一个Activity的状态管理类,并使其支持判断前后台,那么如下:

typescript 复制代码
public final class ActivityStack {

    private static final LinkedList<Activity> sActivityStack = new LinkedList<>();

    private static Boolean isInBackground = true;

    private static WeakHashMap<Activity, String> sStartActivityWeakRef = new WeakHashMap<>();

    private static final CopyOnWriteArrayList<IActivityStackListener> sActivityStackListeners = new CopyOnWriteArrayList<>();


    public static void init(Application application) {
        application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                synchronized (ActivityStack.class) {
                    sActivityStack.remove(activity);
                    sActivityStack.add(activity);
                    notifyActivityStackListener(activity, ActivityStackStatus.CREATE);
                }
            }

            @Override
            public void onActivityStarted(Activity activity) {
                synchronized (ActivityStack.class) {
                    sStartActivityWeakRef.put(activity, activity.getClass().getName());
                    notifyActivityStackListener(activity, ActivityStackStatus.START);
                }
            }

            @Override
            public void onActivityResumed(Activity activity) {
                synchronized (ActivityStack.class) {
                    if (isInBackground) {
                        isInBackground = false;
                    }
                    notifyActivityStackListener(activity, ActivityStackStatus.RESUME);
                }
            }

            @Override
            public void onActivityPaused(Activity activity) {
            }

            @Override
            public void onActivityStopped(Activity activity) {
                synchronized (ActivityStack.class) {
                    sStartActivityWeakRef.remove(activity);
                    if (!isInBackground && sStartActivityWeakRef.isEmpty()) {
                        isInBackground = true;
                    }
                    notifyActivityStackListener(activity, ActivityStackStatus.STOP);
                }
            }

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

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                sActivityStack.remove(activity);
                notifyActivityStackListener(activity, ActivityStackStatus.DESTROY);
            }
        });
    }

    public static synchronized Boolean getIsInBackground() {
        return isInBackground;
    }

    public static synchronized void addActivityStackListener(IActivityStackListener listener) {
        sActivityStackListeners.add(listener);
    }

    public static synchronized void removeActivityStackListener(IActivityStackListener listener) {
        sActivityStackListeners.remove(listener);
    }

    public static synchronized void notifyActivityStackListener(Activity activity, ActivityStackStatus stackStatus) {
        for (IActivityStackListener listener : sActivityStackListeners) {
            listener.onActivityStackChanged(stackStatus);
        }
    }
}
相关推荐
三少爷的鞋5 小时前
Android 协程实践:为什么不应将 `supervisorScope` 作为常规方案
android
开开心心就好6 小时前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
Pniubi6 小时前
模拟一个充值送token怎么保证幂等?一致性?原子性?
java
企业数字化笔记6 小时前
多租户配额怎么控制?用量口径、并发预留与超额处理的实现方法
java·数据库·spring boot
承渊政道7 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从ChatGLM本地化到LoRA、PEFT的高级微调)
android·人工智能·pytorch·chatglm·本地化部署·大模型开发与微调
巴勒个啦7 小时前
Prompt Engineering 实战:5 个让 AI 生成生产级业务代码的工程模式
java·前端
倚楼听风语7 小时前
Kotlin 协程与 suspend 原理详解
java·算法·kotlin
开开心心就好8 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
weixin_460443568 小时前
Java+Linux私有化训考平台:服务、数据库与终端部署结构解析
java·linux·数据库·私有化部署·企业培训考试系统·企业考试系统
云和数据.ChenGuang8 小时前
python大小整数范围解析
java·开发语言·python