[英]BroadcastReceiver onReceive method called before Fragment onCreate()
I have an IntentService which starts when SplashActivity onCreate called:我有一个 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
Here is my IntentService:这是我的 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 - If I have huge number of contacts, my broadcastReceiver onReceive
method called after Fragment creation, which is ok. 1 - 如果我有大量的联系人,我的 broadcastReceiver
onReceive
方法会在 Fragment 创建后调用,这没关系。
2 - If I have a few number of fragment, onReceive
method called before Fragment creation, which does not update my UI at all. 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);
}
};
What is the solution for 2nd case?第二种情况的解决方案是什么?
Start by getting rid of the system broadcast.首先摆脱系统广播。 Assuming your code does what is described, you are leaking all the user's contacts to every single app on the device .
假设您的代码执行所描述的操作,则您将所有用户的联系人泄露给设备上的每个应用程序。 So, beyond the performance problems and the chance of crashing the app with a too-big
Intent
, you have a major privacy hole.因此,除了性能问题和使用太大
Intent
导致应用程序崩溃的可能性之外,您还有一个重大的隐私漏洞。
Then, get rid of the IntentService
.然后,摆脱
IntentService
。 It is deprecated, and it is unnecessary if all you are doing with this data is using it in a UI.它已被弃用,如果您对这些数据所做的一切都是在 UI 中使用它,那么它是不必要的。
Instead, set up a singleton repository that manages your access to the contacts.相反,设置一个 singleton 存储库来管理您对联系人的访问。 Have your activity's
ViewModel
call some method on the repository to do that, where the repository uses an ordinary background thread (perhaps through an Executor
or RxJava type).让您的活动的
ViewModel
调用存储库上的某个方法来执行此操作,其中存储库使用普通后台线程(可能通过Executor
或 RxJava 类型)。 The repository can emit an event when the work is completed, such as via LiveData
or RxJava.存储库可以在工作完成时发出事件,例如通过
LiveData
或 RxJava。 Your ViewModel
can use LiveData
for letting the UI layer know about the data so it can update the UI.您的
ViewModel
可以使用LiveData
让 UI 层了解数据,以便它可以更新 UI。 And, since LiveData
is a value holder, it will hold the value even if the value arrives before the fragment is ready for it.而且,由于
LiveData
是一个值持有者,即使值在片段准备好之前到达,它也会持有该值。
This approach (repository object with a reactive API) is part of Google's general architecture recommendations.这种方法(具有反应式 API 的存储库 object)是 Google 通用架构建议的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.