You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:23:09