gpt4 book ai didi

java - 为什么备份相关过程可能会导致应用程序的 onCreate 未执行?

转载 作者:IT老高 更新时间:2023-10-28 20:54:12 29 4
gpt4 key购买 nike

Application 类如下是很常见的

public class WeNoteApplication extends MultiDexApplication {
public static WeNoteApplication instance() {
return me;
}

@Override
public void onCreate() {
super.onCreate();

me = this;

在正常情况下,ApplicationonCreate总是会在入口点Activity的onCreate之前被调用。

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Normally, it will NOT be null.
android.util.Log.i("CHEOK", "WeNoteApplication -> " + WeNoteApplication.instance());

但是,如果我在应用启动时运行以下命令

c:\yocto>adb shell bmgr restore com.yocto.wenote
restoreStarting: 1 packages
onUpdate: 0 = com.yocto.wenote
restoreFinished: 0
done

应用程序将关闭。如果,我点击应用程序图标再次启动。这就是发生的事情

  1. ApplicationonCreate没有执行!
  2. ActivityonCreate被执行,WeNoteApplication.instance()null

我查看了一些 Google 的 Android 源代码(例如 WorkManager)

https://github.com/googlecodelabs/android-workmanager/issues/80

在他们的评论中,他们声明

// 1. The app is performing an auto-backup.  Prior to O, JobScheduler could erroneously
// try to send commands to JobService in this state (b/32180780). Since neither
// Application#onCreate nor ContentProviders have run,...

看来,如果涉及到备份相关的过程,ApplicationonCreate就不会被执行了!

为什么会这样?这种行为是否曾经记录在某个地方?


问题跟踪器

https://issuetracker.google.com/issues/138423608


错误演示的完整示例

https://github.com/yccheok/AutoBackup-bug

最佳答案

您可以使用此解决方法绕过您的问题。

这背后的想法是创建一个自定义的 BackupAgent 来接收 onRestoreFinished 事件的通知,然后杀死你的进程,这样下次你将打开应用程序系统将创建您的自定义应用程序类。

通常使用自定义 BackupAgent 会强制您实现抽象方法 onBackuponRestore,它们用于键值备份。幸运的是,如果您在 list 中指定 android:fullBackupOnly,系统将改用基于文件的自动备份,如 here 所述。 .

首先,创建自定义BackupAgent:

package com.yocto.cheok;

import android.app.ActivityManager;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.Process;

import java.util.List;

public class CustomBackupAgent extends BackupAgent {

private Boolean isRestoreFinished = false;

@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) {
//NO-OP - abstract method
}

@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) {
//NO-OP - abstract method
}

@Override
public void onRestoreFinished() {
super.onRestoreFinished();

isRestoreFinished = true;
}

@Override
public void onDestroy() {
super.onDestroy();

if (isRestoreFinished) {
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

if (activityManager != null) {
final List<ActivityManager.RunningAppProcessInfo> runningServices = activityManager.getRunningAppProcesses();

if (runningServices != null &&
runningServices.size() > 0 &&
runningServices.get(0).processName.equals("com.yocto.cheok")
) {
Process.killProcess(runningServices.get(0).pid);
}
}
}
}
}

然后将 android:backupAgent="com.yocto.cheok.CustomBackupAgent"android:fullBackupOnly="true" 添加到 Android list 中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yocto.cheok">

<application
android:name="com.yocto.cheok.CheokApplication"
android:allowBackup="true"
android:backupAgent="com.yocto.cheok.CustomBackupAgent"
android:fullBackupContent="@xml/my_backup_rules"
android:fullBackupOnly="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.yocto.cheok.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

下次您将在恢复后享用该应用程序时,您将获得:

2019-07-28 22:25:33.528 6956-6956/com.yocto.cheok I/CHEOK: CheokApplication onCreate
2019-07-28 22:25:33.642 6956-6956/com.yocto.cheok I/CHEOK: In MainActivity, CheokApplication = com.yocto.cheok.CheokApplication@7b28a29

关于java - 为什么备份相关过程可能会导致应用程序的 onCreate 未执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57211036/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com