繁体   English   中英

android:process 导致 MyApplication 的 onCreate 方法被调用两次。 如何防止代码运行两次?

[英]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

  • 我们只需要一种方法来存储一个 boolean 变量,该变量指示MyApplicationonCreate()方法是否第一次被调用,使用这种解决方案似乎效率低下。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM