问题描述
Application
类通常如下
public class WeNoteApplication extends MultiDexApplication {
public static WeNoteApplication instance() {
return me;
}
@Override
public void onCreate() {
super.onCreate();
me = this;
在正常情况下,Application
的onCreate
总是会在入口点Activity
的onCreate之前被调用.
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
Application
的onCreate
没有执行!Activity
的onCreate
被执行,WeNoteApplication.instance()
为null
Application
'sonCreate
is not executed!Activity
'sonCreate
is executed, andWeNoteApplication.instance()
isnull
我查看了一些 Google 的 Android 源代码(例如 WorkManager
)
I look at some Google's Android source code (WorkManager
for instance)
https://github.com/googlecodelabs/android-workmanager/issues/80
在他们的评论中,他们指出
In their comment, they states that
// 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,...
看来,如果涉及到备份相关的过程,Application
的onCreate
是不会被执行的!
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
事件的通知,然后终止您的进程,以便下次您打开应用程序时系统将创建您的自定义应用程序类.
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
强制您实现抽象方法onBackup
和onRestore
,用于键值备份.幸运的是,如果您在清单中指定 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
这篇关于为什么备份相关过程可能会导致Application的onCreate没有执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!