Метод BroadcastReceiver onReceive, вызываемый перед Fragment onCreate () - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть 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 метод вызывается до создания фрагмента, который вообще не обновляет мой пользовательский интерфейс.

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);
        }
    };

Какое решение для второго случая?

1 Ответ

0 голосов
/ 08 апреля 2020

Начните с избавления от системной трансляции. Предполагая, что ваш код выполняет то, что описано, вы пропускаете все контакты пользователя в каждое приложение на устройстве . Таким образом, помимо проблем с производительностью и вероятности сбоя приложения с слишком большим Intent, у вас есть большая дыра в конфиденциальности.

Затем избавьтесь от IntentService. Это устарело, и в этом нет необходимости, если все, что вы делаете с этими данными, использует их в пользовательском интерфейсе.

Вместо этого установите одноэлементный репозиторий, который управляет вашим доступом к контактам. Пусть ваша деятельность ViewModel вызовет какой-то метод в хранилище, чтобы сделать это, когда в хранилище используется обычный фоновый поток (возможно, через тип Executor или Rx Java). По завершении работы хранилище может выдать событие, например, через LiveData или Rx Java. Ваш ViewModel может использовать LiveData для информирования слоя пользовательского интерфейса о данных, чтобы он мог обновлять пользовательский интерфейс. И, поскольку LiveData является держателем значения, оно будет содержать значение, даже если значение поступит до того, как фрагмент будет готов для него.

Этот подход (объект репозитория с реактивным API) является частью общего Google архитектурные рекомендации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...