Как сделать запрос к базе данных комнаты в IntentService без исключения - PullRequest
0 голосов
/ 13 февраля 2019

Я запрашиваю POJO, который является НЕ наблюдаемым / неживым данными из IntentService , который был запущен в PreferenceFragment .Однако через секунду мое приложение дает сбой и отображается журнал:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:204)
    at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:232)
    at vault.dao.xxxDao_Impl.getAllNonLivePojoItems(xxxDao_Impl.java:231)

Я хочу знать, почему моя программа выдает это исключение.согласно https://stackoverflow.com/a/23935791/8623507

мои запросы к базе данных находятся внутри IntentService, который выполняется в своем собственном потоке, поэтому я должен быть в зеленом.вот мой код:

Inside IntentService
--------------------

// ERROR OCCURS HERE
List<POJO> pojoList = localRepo.getAllNonLivePojoItems(); // <= ERROR POINTS HERE
    if (pojoList != null && pojoList.size() > 0) {
        for (Pojo pojo : pojoList ){
           // Do Long Running Task Here ....
    }

Также я создаю экземпляры используемых объектов и вызываю вышеупомянутые методы из этих объектов на протяжении IntentService в OnHandleIntent примерно так:

@Override
protected void onHandleIntent(Intent intent) {
    if (intent != null) {
        final String action = intent.getAction();
        LocalRepo localRepo = new LocalRepo(this.getApplication());
        PojoHelper pojoHelper = new PojoHelper(this, localRepo);

        if (LOGOUT.equals(action) && type != null) {
            Log.d(TAG, "onHandleIntent: LOGOUT");
            pojoHelper.logoutPojo();
        } 
        else if(DELETE.equals(action) && type != null){
            Log.d(TAG, "onHandleIntent: DELETE_POJO");
            pojoHelper.deletePojo(true);
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Я предполагаю, что вы получаете обратный вызов от AsyncTask метода onPostExecute (), который выполняется в потоке пользовательского интерфейса.Запрещается использовать вызовы базы данных или сети внутри потока пользовательского интерфейса, поскольку он может блокировать пользовательский интерфейс.

Выполнить код при доступе к базе данных в новом потоке.

Пример:

        Executors.newSingleThreadExecutor().execute(()->{
             //TODO access Database
         });
0 голосов
/ 13 февраля 2019

Одна вещь, которую я не упомянул, состояла в том, что метод выполнялся в методе обратного вызова асинхронного ответа

PojoWarehouse.processPojoItems(new AsyncPojoCallback() {
    @Override
    public void done(Exception e) {
        if (e == null) {
            // ERROR OCCURS HERE
            List<POJO> pojoList = localRepo.getAllNonLivePojoItems(); // <= ERROR POINTS HERE
            if (pojoList != null && pojoList.size() > 0) {
                for (Pojo pojo : pojoList ){
                // Do Long Running Task Here ....
            }
        } else
                Log.d(TAG, "done: Error Logging Out: " + e.getLocalizedMessage());
        }
    });

Я не могу объяснить на техническом уровне, почему это исправило проблему, однако предложения приветствуются.

...