You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android平台Ionic/Cordova应用Paused状态被杀后重启异常问询

解决Ionic/Cordova相机插件导致Activity被系统杀死的问题

首先,我来针对你的两个疑问逐一分析,再结合你补充的日志给出具体的解决方案:

疑问1:系统杀死Paused状态的Activity后能否恢复?有没有Workaround?

正常情况下,Android系统在杀死处于Paused/Stopped状态的Activity后,当用户从相机返回时,应该会自动重建Activity并尝试通过onSaveInstanceState保存的Bundle恢复状态。但你遇到的情况是系统明明执行了onSaveInstanceState,却声称“no saved state”,这是核心矛盾点。

针对这种系统强制杀死进程的场景,常见的Workaround包括:

  • 手动持久化关键状态:不要完全依赖onSaveInstanceState(系统内存极度紧张时,这个Bundle可能也会丢失),把应用的关键状态(比如当前页面、用户输入内容)保存到SharedPreferences或本地文件,在onCreate时主动读取恢复。
  • 优化内存占用:减少系统杀死进程的概率,这是从根源解决问题的关键。
  • 调整相机插件的使用方式:避免长时间占用高内存的相机资源,比如拍完照后及时释放相机相关的资源。

疑问2:如何排查未触发异常处理器的崩溃?

你提到异常处理器没触发,这是因为系统直接杀死进程不属于代码抛出的未捕获异常,而是系统的资源回收行为,所以你的UncaughtExceptionHandler不会生效。

排查方向可以从这几点入手:

  1. 深挖系统日志:重点关注ActivityManager的日志(用adb logcat -s ActivityManager过滤),你已经看到了进程被杀死的日志,继续找系统杀死进程的具体原因(比如是否是Low Memory Killer触发的),有没有伴随“Low Memory”相关的提示。
  2. 监控内存变化:用Android Studio的Profiler工具,实时监控打开相机前后的内存占用情况,看看是否有内存飙升或内存泄漏的情况(你说内存约350MB,可能在某些低内存设备上已经接近阈值)。
  3. 检查相机插件的兼容性:确认你使用的cordova-plugin-camera版本是否有已知的生命周期bug,尝试升级到最新稳定版,或者替换为更轻量的相机插件(比如cordova-plugin-camera-preview如果符合你的使用场景)。

针对你补充的日志场景:执行了onSaveInstanceState但系统仍无保存状态的解决方案

从日志来看,系统执行了onSaveInstanceState但后续声称“no saved state”,大概率是因为Cordova的WebView状态没有被正确保存——默认的super.onSaveInstanceState可能没有处理WebView的状态,导致重建时无法恢复WebView的内容,进而让系统认为没有有效状态。

你可以尝试以下修改:

1. 手动保存/恢复WebView状态

修改你的MainActivity代码,在onSaveInstanceState中保存WebView状态,在onCreate中恢复:

public class MainActivity extends CordovaActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.e("com.xxx.test", "onCreate");
        super.onCreate(savedInstanceState);
        
        Bundle extras = getIntent().getExtras();
        if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
            moveTaskToBack(true);
        }

        loadUrl(launchUrl);
        
        // 恢复WebView状态
        if (savedInstanceState != null && this.appView != null) {
            this.appView.restoreState(savedInstanceState);
        }
        
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                Log.e("com.xxx.test", "onCreate, UNCAUGHT EXCEPTION!!!");
                System.exit(2);
            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        Log.e("com.xxx.test", "onSaveInstanceState");
        // 先保存WebView状态
        if (this.appView != null) {
            this.appView.saveState(savedInstanceState);
        }
        super.onSaveInstanceState(savedInstanceState);
    }

    // 其他生命周期方法保持不变...
}

2. 优化相机插件的内存占用

调用相机时,尽量限制图片的分辨率,避免加载过大的图片导致内存暴增:
比如在Ionic代码中调用相机时,设置targetWidthtargetHeight

import { Camera, CameraOptions } from '@ionic-native/camera/ngx';

const options: CameraOptions = {
  quality: 80,
  targetWidth: 1024, // 缩小图片宽度
  targetHeight: 1024, // 缩小图片高度
  destinationType: this.camera.DestinationType.FILE_URI,
  encodingType: this.camera.EncodingType.JPEG,
  mediaType: this.camera.MediaType.PICTURE
};

this.camera.getPicture(options).then((imageData) => {
  // 处理图片
}, (err) => {
  // 处理错误
});

3. 给应用分配更多内存(谨慎使用)

config.xml中添加配置,让应用使用更大的堆内存:

<platform name="android">
    <edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application">
        <application android:largeHeap="true" />
    </edit-config>
</platform>

注意:这个方法会占用更多系统资源,可能影响其他应用,仅在必要时使用。

4. 清理WebView缓存

在应用进入后台时,清理WebView的不必要缓存,释放内存:

@Override
public void onPause() {
    Log.e("com.xxx.test", "onPause");
    if (this.appView != null) {
        this.appView.clearCache(true);
        // 也可以清理历史记录等
        // this.appView.clearHistory();
    }
    super.onPause();
}

通过以上步骤,应该能大幅减少系统杀死Activity的概率,同时即使被杀死,也能正确恢复应用状态。

内容的提问来源于stack exchange,提问作者charon1664

火山引擎 最新活动