Android 10以上版本页面跳转崩溃问题求助(API>29)
从报错信息和现象来看,核心问题是AppConfig.getInstance().company在Android 13及以上版本中变为null,导致调用getIdSociete()时触发空指针异常。以下是针对性的排查方向和解决方法:
1. 优先排查进程重启问题
Android 10+(尤其是Android 12+)对后台进程的回收机制更严格,当应用从后台切换回前台、或者页面跳转触发系统资源回收时,可能导致Application进程被杀死后重建。此时内存中的单例AppConfig状态会丢失,登录时存入的company对象自然也会变为null。
验证方法:
在自定义Application类的onCreate()方法中添加日志,登录后跳转页面时观察日志是否重复打印——如果重复打印,说明进程确实被重启了。
解决方法:
将company数据持久化到本地存储(如SharedPreferences、Room数据库),而非仅存在内存单例中。修改AppConfig的逻辑:
- 设置
company时同步写入本地存储 - 单例初始化时优先从本地存储恢复
company对象
示例代码:
public class AppConfig { private static volatile AppConfig instance; private Societe company; private final Context appContext; private static final String PREF_NAME = "AppConfigPrefs"; private static final String KEY_ID_SOCIETE = "idSociete"; private AppConfig(Context context) { this.appContext = context.getApplicationContext(); // 初始化时从本地存储恢复数据 loadCompanyFromPrefs(); } public static AppConfig getInstance(Context context) { if (instance == null) { synchronized (AppConfig.class) { if (instance == null) { instance = new AppConfig(context); } } } return instance; } public void setCompany(Societe company) { this.company = company; // 持久化数据到SharedPreferences saveCompanyToPrefs(company); } private void saveCompanyToPrefs(Societe company) { SharedPreferences prefs = appContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(KEY_ID_SOCIETE, company.getIdSociete()); // 如需保存其他字段,在此添加对应put操作 editor.apply(); } private void loadCompanyFromPrefs() { SharedPreferences prefs = appContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); int idSociete = prefs.getInt(KEY_ID_SOCIETE, -1); if (idSociete != -1) { company = new Societe(); company.setIdSociete(idSociete); // 恢复其他字段 } } }
2. 检查单例实现的线程安全性与全局唯一性
如果AppConfig的单例实现存在线程安全问题,或者没有使用Application级别的Context,可能导致在多线程场景下创建多个实例,其中某个实例的company字段未被初始化。
检查要点:
- 单例是否使用双重检查锁定(如上述示例)确保线程安全
- 构造方法是否传入
getApplicationContext()而非Activity Context,避免内存泄漏同时保证全局唯一
3. 验证数据持久化的时机与完整性
登录后存储company的逻辑可能存在异步延迟,导致页面跳转时数据尚未写入完成,从而读取到null。
解决方法:
确保登录接口返回数据后,同步完成AppConfig.setCompany()调用,再执行页面跳转操作。如果使用异步回调,需在回调完成后再启动目标Activity。
4. 排查多进程场景
如果应用存在多进程配置(如某些组件指定了android:process属性),单例AppConfig会在每个进程中独立初始化,导致其他进程无法获取主进程中存储的company数据。
解决方法:
- 移除不必要的多进程配置
- 若必须使用多进程,改用跨进程存储方案(如ContentProvider、MMKV)共享数据
内容的提问来源于stack exchange,提问作者Insou

