当前位置: 首页 > 面试题库 >

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

尉迟鸿熙
2023-03-14
问题内容

通常有以下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事件通知,然后终止您的进程,因此,下次您打开该应用程序时,系统将创建您的自定义Application类。

通常使用自定义BackupAgent强制您实现用于键值备份的抽象方法onBackuponRestore。幸运的是,如果你指定android:fullBackupOnly在清单中,该系统将使用基于文件的自动备份,而不是作为解释在这里。

首先,创建自定义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清单中:

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


 类似资料:
  • fReceiveBuffer是否存在一个视频帧? 哦,这里是我的FFMPEG初始化代码,需要打开相关视频解码器:http://paste.ubuntu.com/12529760//

  • 我洛基,在“开始”之后,我遵循https://getbootstrap.com/docs/4.3/layout/overview/的指示(我猜在那个例子中缺少了一些东西) 我说: 链接到头标签中的css文件 但是它不起作用,类“hid-ph-flex”总是在“代码”显示中:无“代码”,火狐调试器警告说:“未知规则或错误读取规则在“包括” 我想我忘了一份文件,有什么帮助吗???

  • 我是react native的新手,我正在尝试使用android Studio开始我的第一个项目。我遵循react native的“设置开发环境”中的说明,最终使用 然后我在android studio中打开了我的项目来启动AVD,但是gradle抛出了以下错误 错误:评估脚本时出现问题。 无法运行程序“node”(在目录“/home/deadshot/documents/playground/a

  • 如果我有一个模型序列化程序,其中数据库模型中不需要first_name和last_name(blank=True,null=True,default=None),并且我选择提交可能包含或可能不包含“first_name”或“last_name”字段的json数据,那么无论这些字段是否通过json请求提交,这些字段不应该存在于已验证的_数据[]中,因为它们列在序列化程序字段中,并且其默认值设置为无?

  • 我有这个项目。然后我做以下步骤: 转到 预期结果:错误消息(在浏览器中呈现) 白标签错误页 此应用程序没有 /error的显式映射,因此您将此视为一种退回。星期二八月27 16:59:23CEST 2019有一个意外的错误(类型=未找到,状态=404)。没有可用的消息 如何更改附加的代码,使文件索引代替此错误。是否呈现xhtml? 更新1:如果我去,我得到这个错误: 白标签错误页此应用程序没有/E

  • 我正在使用Reverfit2,我试图从我用Python制作的Web服务中请求一些数据。 实际上,它抛出了一个“java.lang.IllegalStateException”,但是当我调用GET方法时,API返回代码200,而且我还可以看到用于调试响应JSON的打印版本。问题是Call方法,因为它总是在failure时执行。 求求你,救命! 这是我的(简单的)Python Web服务,API-Pr