BroadcastReceiver onReceive 方法在 Fragment onCreate() 之前调用

BroadcastReceiver onReceive method called before Fragment onCreate()

我有一个 IntentService,它在调用 SplashActivity onCreate 时启动:

class SplashActivity : AppCompatActivity() {

    private val handler = Handler(Looper.getMainLooper())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        startService(Intent(applicationContext, ContactsService::class.java))
        handler.postDelayed({
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
        }, SPLASH_DELAY.toLong())
    }
}

private const val SPLASH_DELAY = 1500

这是我的 IntentService :

override fun onHandleIntent(intent: Intent?) {
        val cursor = ContactUtil.getContactsCursor(null, null, this)
        val contacts = ContactUtil.getContacts(cursor, this)
        cursor?.close()
        val contactsIntent = Intent(CONTACTS_RECEIVER)
        contactsIntent.putParcelableArrayListExtra(CONTACTS, ArrayList<Parcelable>(contacts))
        sendBroadcast(contactsIntent)
    }

1 - 如果我有大量联系人,我的 broadcastReceiver onReceive 方法会在片段创建后调用,这没问题。

2 - 如果我有几个片段,onReceive 方法在片段创建之前调用,根本不会更新我的 UI。

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            List<Contact> contacts = intent.getParcelableArrayListExtra(CONTACTS);
            mContacts = contacts;
            mAdapter.setItems(contacts, true);
            mProgressBar.setVisibility(View.GONE);
            mAppBarLayout.setVisibility(View.VISIBLE);
            mRecyclerView.setVisibility(View.VISIBLE);
        }
    };

第二种情况的解决方案是什么?

首先摆脱系统广播。假设您的代码执行所描述的操作,您会将所有用户的联系人泄露给设备上的每个应用程序。因此,除了性能问题和应用过大 Intent 导致应用程序崩溃的可能性之外,您还有一个重大的隐私漏洞。

然后,去掉IntentService。它已被弃用,如果您对这些数据所做的一切都是在 UI.

中使用它,则没有必要

相反,设置一个单独的存储库来管理您对联系人的访问。让你的 activity 的 ViewModel 调用存储库上的一些方法来执行此操作,其中存储库使用普通后台线程(可能通过 Executor 或 RxJava 类型)。存储库可以在工作完成时发出事件,例如通过 LiveData 或 RxJava。您的 ViewModel 可以使用 LiveData 让 UI 层知道数据,以便它可以更新 UI。而且,由于 LiveData 是一个值持有者,即使值在片段准备好之前到达,它也会持有该值。

这种方法(具有反应性 API 的存储库对象)是 Google 的一般架构建议的一部分。