[英]android:process causes my MyApplication's onCreate method to be called twice. How can I prevent the code running twice?
我知道如果我在清单中使用android:process
那么扩展 Application 的 class 将被调用两次。 一次,用于应用程序,第二次用于新流程。
问题是我在 MyApplication(扩展应用程序)中有不应调用两次的代码。 我想要一个单独的进程,但我只希望 MyApplication#onCreate 中的代码每次加载都运行一次。
我尝试在共享首选项中设置一个标志,但它不起作用,可能是因为不同的进程问题
有任何想法吗?
根本原因
来自SharedPreferences文档:
注意:此 class 不支持跨多个进程使用。
这就解释了为什么您的SharePreferences
不起作用。
解决方案 1:使用Context.MODE_MULTI_PROCESS ,但在 API 级别 23 中已弃用
public static final int MODE_MULTI_PROCESS
此常量在 API 级别 23 中已弃用。
MODE_MULTI_PROCESS 在 Android 的某些版本中不能可靠地工作,而且不提供任何机制来协调跨进程的并发修改。 应用程序不应尝试使用它。 相反,他们应该使用明确的跨进程数据管理方法,例如 ContentProvider。
解决方案 2:使用ContentProvider
2.1。 编写自己的ContentProvider
MyApplication
的onCreate()
方法是否第一次被调用,使用这种解决方案似乎效率低下。 2.2. 使用来自 Android 的预定义ContentProvider
解决方案3:我们可以使用下面的流程来实现
声明一个与您的应用程序在同一进程中运行的BroadcastReceiver
。 因为它们在同一个进程上运行,所以它们具有相同的进程 ID。
在单独的进程(私有或全局)上运行的组件(活动、服务、接收者、提供者),因此它们将具有不同的进程 ID。
执行
步骤 1.创建一个从 BoardcastReceiver 扩展的BoardcastReceiver
,命名为AppReceiver
。
public class AppReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Messenger messenger = intent.getParcelableExtra(MyApplication.EXTRA_MESSENGER);
int processId = intent.getIntExtra(MyApplication.EXTRA_PROCESS_ID, -1);
boolean isOnCreateCalledFirstTime = processId == Process.myPid();
Message message = Message.obtain();
message.arg1 = isOnCreateCalledFirstTime ? 1 : 0;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
步骤 2.将 class 添加到AndroidManifest.xml
<receiver
android:name=".AppReceiver"
android:enabled="true"
android:exported="true" />
步骤 3.修改您的MyApplication
class
public class MyApplication extends Application {
public static final String EXTRA_MESSENGER = "EXTRA_MESSENGER";
public static final String EXTRA_PROCESS_ID = "EXTRA_PROCESS_ID";
@Override
public void onCreate() {
super.onCreate();
Intent intent = new Intent();
String pkg = getPackageName();
intent.setComponent(new ComponentName(pkg, pkg + ".AppReceiver"));
Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
boolean isOnCreateCalledFirstTime = msg.arg1 != 0;
if (isOnCreateCalledFirstTime) {
// TODO: First time onCreate() is called
} else {
// TODO: Next time onCreate() is called
}
return true;
}
});
Messenger messenger = new Messenger(handler);
intent.putExtra(EXTRA_MESSENGER, messenger);
intent.putExtra(EXTRA_PROCESS_ID, Process.myPid());
sendBroadcast(intent);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.