如何在IntentService中查询会议室数据库而不会引发异常

时间:2019-02-13 06:22:26

标签: android android-room intentservice hang

我正在查询POJO,它是从 PreferenceFragment 中启动的 IntentService 中的不可观测/非实时数据。但是一秒钟我的应用程序崩溃并显示日志:

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 ....
    }

我还要实例化正在使用的对象,并在整个 OnHandleIntent 中的 IntentService 中从这些对象中调用上述方法,如下所示:

@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 :(得分:1)

我假设您从AsyncTask onPostExecute()方法获得回调,该方法在UI线程上运行。禁止在UI线程内使用数据库或网络调用,因为它会阻止UI。

在新线程中访问数据库的地方执行代码。

示例:

        Executors.newSingleThreadExecutor().execute(()->{
             //TODO access Database
         });

答案 1 :(得分:0)

我没有提到的一件事是该方法是在异步响应回调方法中执行的

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

我无法在技术层面上解释为什么此问题得以解决,但是我们欢迎您提出建议。