为什么备份相关的过程可能导致应用程序的onCreate不执行? [英] Why backup related process might cause Application's onCreate is not executed?

查看:77
本文介绍了为什么备份相关的过程可能导致应用程序的onCreate不执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常具有Application类如下

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

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

        me = this;


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


During normal circumstance, Application's onCreate will always be called before entry point Activity's 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());

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

However, if I run the following command while the app is launched

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

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

The app will be closed. If, I tap on the app icon to launch again. This is what happens

  1. ApplicationonCreate未执行!
  2. ActivityonCreate被执行,而WeNoteApplication.instance()null
  1. Application's onCreate is not executed!
  2. Activity's onCreate is executed, and WeNoteApplication.instance() is null

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

I look at some Google's Android source code (WorkManager for instance)

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将不会执行!

It seems that, if backup related process is involved, Application's onCreate will not be executed!

为什么会这样呢?这种行为曾经在某些地方被记录过吗?

Why it is so? Is this behavior ever documented some where?

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

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

推荐答案

您可以使用此替代方法来绕过您的问题.

You can bypass your issue with this workaround.

其背后的想法是创建一个自定义BackupAgent来接收onRestoreFinished事件的通知,然后终止您的进程,因此,下次您打开该应用程序时,系统将创建您的自定义Application类.

The idea behind this is to create a custom BackupAgent to receive notification of onRestoreFinished event and then kill your process, so the next time you will open the app the system will create your custom Application class.

通常使用自定义BackupAgent强制您实现用于键值备份的抽象方法onBackuponRestore.幸运的是,如果您在清单中指定android:fullBackupOnly,则系统将改为使用基于文件的自动备份,如

Usually using a custom BackupAgent force you to implement the abstract methods onBackup and onRestore, which are used for key-value backup. Luckily if you specify android:fullBackupOnly in the manifest, the system will use the file-based Auto Backup instead, as explained 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清单中:

then add android:backupAgent="com.yocto.cheok.CustomBackupAgent" and android:fullBackupOnly="true" to the Android manifest:

<?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>

下次还原后,您将在应用程序中午餐,您将获得:

Next time you will lunch the app after a restore you will get:

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

这篇关于为什么备份相关的过程可能导致应用程序的onCreate不执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆