Android应用关闭后静态变量未重置的原因及解决方法咨询
问题原因与解决方案
问题原因
Android系统中,调用finishAffinity()关闭Activity、stopSelf()停止前台服务后,应用进程不会立即被销毁。系统会根据当前内存资源情况决定是否将进程缓存(比如内存充足时,进程会被保留在后台)。由于静态变量属于类成员,类的加载与卸载绑定在进程的虚拟机生命周期上,只要进程未被销毁,类就不会被卸载,静态变量的值会一直保留。当你再次启动应用时,系统直接复用了之前缓存的进程,因此静态变量还是上次修改后的true。
解决方案
1. 借助Application生命周期自动重置
自定义Application类,在其onCreate()方法中重置静态变量。因为无论应用是首次启动还是复用进程启动,Application.onCreate()只会执行一次:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Context.setProgramClosing(false); } }
在AndroidManifest.xml中配置该Application:
<application android:name=".MyApplication" <!-- 其他原有配置 --> > <!-- 组件声明 --> </application>
2. 用SharedPreferences替代静态变量存储状态
如果不需要依赖进程生命周期,或者希望状态在进程销毁后也能保留,改用SharedPreferences存储状态:
修改Context类:
public class Context { private static final String PREFS_NAME = "AppStatePrefs"; private static final String KEY_IS_CLOSING = "is_program_closing"; public static void setProgramClosing(Context context, boolean isClosing) { SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, android.content.Context.MODE_PRIVATE); prefs.edit().putBoolean(KEY_IS_CLOSING, isClosing).apply(); } public static boolean isProgramClosing(Context context) { SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, android.content.Context.MODE_PRIVATE); return prefs.getBoolean(KEY_IS_CLOSING, false); } }
调用时传入上下文:
// MainActivity中 String msg = "onCreate, isProgramClosing: " + Context.isProgramClosing(this); // MainService中 Context.setProgramClosing(this, true);
3. 监听组件生命周期精确控制
通过注册ActivityLifecycleCallbacks监听所有Activity的销毁状态,结合服务运行状态,在应用完全退出时重置静态变量:
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { private int activeActivityCount = 0; @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { activeActivityCount++; } @Override public void onActivityDestroyed(@NonNull Activity activity) { activeActivityCount--; // 所有Activity销毁且服务已停止时重置变量 if (activeActivityCount == 0 && !isServiceRunning(MainService.class)) { Context.setProgramClosing(false); } } // 以下方法空实现即可 @Override public void onActivityStarted(@NonNull Activity activity) {} @Override public void onActivityResumed(@NonNull Activity activity) {} @Override public void onActivityPaused(@NonNull Activity activity) {} @Override public void onActivityStopped(@NonNull Activity activity) {} @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} }); } private boolean isServiceRunning(Class<?> serviceClass) { ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { return true; } } return false; } }
内容的提问来源于stack exchange,提问作者Alex Dzhus
相关产品推荐
相关产品推荐

