-
引言
- 介绍
AppHolder
的作用:全局管理Application
和Activity
,简化开发。 - 适用场景:需要全局上下文和生命周期管理的场景。
- 介绍
-
功能特性
- 全局上下文管理。
- Activity 生命周期监听。
- Fragment 生命周期监听(可选)。
- 应用状态判断(是否在前台)。
- Activity 操作(关闭指定 Activity、关闭所有 Activity 等)。
- 完全退出应用。
AppHolder
类
package cn.wandersnail.commons.base;import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;/*** AppHolder - 全局 Application 和 Activity 管理工具类** 功能:* 1. 全局持有 Application 上下文。* 2. 管理所有 Activity 的生命周期。* 3. 支持 Fragment 生命周期监听。* 4. 提供应用状态判断、Activity 操作等功能。** 使用方式:* 1. 在 Application 中初始化:AppHolder.initialize(this);* 2. 通过 AppHolder.getInstance() 获取单例对象。*/
public class AppHolder extends FragmentManager.FragmentLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {// 单例实例private static final class Holder {private static final AppHolder INSTANCE = new AppHolder();}// 正在运行的 Activity 信息private static class RunningActivity {String name; // Activity 类名WeakReference<Activity> weakActivity; // Activity 弱引用RunningActivity(String name, WeakReference<Activity> weakActivity) {this.name = name;this.weakActivity = weakActivity;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof RunningActivity)) return false;RunningActivity that = (RunningActivity) o;return name.equals(that.name);}@Overridepublic int hashCode() {return Objects.hash(name);}}// 成员变量private final Map<String, RunningActivity> runningActivities = new ConcurrentHashMap<>(); // 正在运行的 Activityprivate final Map<String, WeakReference<Fragment>> runningFragments = new ConcurrentHashMap<>(); // 正在运行的 Fragmentprivate boolean isCompleteExit = false; // 是否完全退出private Application application; // Application 实例private Looper mainLooper; // 主线程 Looperprivate RunningActivity topActivity; // 栈顶 Activity// 私有构造方法private AppHolder() {mainLooper = Looper.getMainLooper();}/*** 获取 AppHolder 单例实例*/@NonNullpublic static AppHolder getInstance() {return Holder.INSTANCE;}/*** 初始化 AppHolder** @param application Application 实例*/public static void initialize(@NonNull Application application) {Objects.requireNonNull(application, "Application cannot be null");Holder.INSTANCE.application = application;application.registerActivityLifecycleCallbacks(Holder.INSTANCE);}/*** 获取全局上下文*/@NonNullpublic Context getContext() {if (application == null) {throw new IllegalStateException("AppHolder has not been initialized. Call AppHolder.initialize(app) first.");}return application;}/*** 判断当前是否在主线程*/public boolean isMainThread() {return Looper.myLooper() == mainLooper;}/*** 获取主线程 Looper*/@NonNullpublic Looper getMainLooper() {return mainLooper;}/*** 判断应用是否在前台*/public boolean isAppOnForeground() {ActivityManager am = (ActivityManager) application.getSystemService(Context.ACTIVITY_SERVICE);if (am != null) {List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();if (processes != null) {for (ActivityManager.RunningAppProcessInfo process : processes) {if (application.getPackageName().equals(process.processName)) {return process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;}}}}return false;}/*** 获取栈顶 Activity*/@Nullablepublic Activity getTopActivity() {return topActivity == null ? null : topActivity.weakActivity.get();}/*** 获取所有正在运行的 Activity*/@NonNullpublic List<Activity> getAllActivities() {List<Activity> activities = new ArrayList<>();for (RunningActivity runningActivity : runningActivities.values()) {Activity activity = runningActivity.weakActivity.get();if (activity != null) {activities.add(activity);}}return activities;}/*** 关闭指定 Activity** @param className 目标 Activity 类名* @param classNames 其他目标 Activity 类名(可选)*/public void finish(@NonNull String className, @Nullable String... classNames) {for (RunningActivity runningActivity : runningActivities.values()) {Activity activity = runningActivity.weakActivity.get();if (activity != null && (activity.getClass().getName().equals(className) || contains(classNames, activity.getClass().getName()))) {activity.finish();}}}/*** 关闭所有 Activity*/public void finishAll() {for (RunningActivity runningActivity : runningActivities.values()) {Activity activity = runningActivity.weakActivity.get();if (activity != null) {activity.finish();}}}/*** 完全退出应用*/public void completeExit() {isCompleteExit = true;finishAll();if (runningActivities.isEmpty()) {android.os.Process.killProcess(android.os.Process.myPid());System.exit(0);}}// Activity 生命周期回调@Overridepublic void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {RunningActivity runningActivity = new RunningActivity(activity.getClass().getName(), new WeakReference<>(activity));runningActivities.put(activity.getClass().getName(), runningActivity);topActivity = runningActivity;}@Overridepublic void onActivityDestroyed(@NonNull Activity activity) {runningActivities.remove(activity.getClass().getName());if (isCompleteExit && runningActivities.isEmpty()) {android.os.Process.killProcess(android.os.Process.myPid());System.exit(0);}}// 其他生命周期方法(略)@Overridepublic void onActivityStarted(@NonNull Activity activity) {}@Overridepublic void onActivityResumed(@NonNull Activity activity) {}@Overridepublic void onActivityPaused(@NonNull Activity activity) {}@Overridepublic void onActivityStopped(@NonNull Activity activity) {}@Overridepublic void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}// Fragment 生命周期回调(略)@Overridepublic void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {runningFragments.put(f.getClass().getName(), new WeakReference<>(f));}@Overridepublic void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {runningFragments.remove(f.getClass().getName());}// 工具方法:判断数组是否包含某元素private boolean contains(String[] array, String value) {if (array != null) {for (String item : array) {if (item.equals(value)) {return true;}}}return false;}
}
使用示例
// 在 Application 中初始化
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();AppHolder.initialize(this);}
}// 获取全局上下文
Context context = AppHolder.getInstance().getContext();// 关闭所有 Activity
AppHolder.getInstance().finishAll();// 判断应用是否在前台
boolean isForeground = AppHolder.getInstance().isAppOnForeground();