无论实际查询花费多长时间,rawQuery总是立即执行

问题描述

我已经花了好几个小时试图了解为什么一个简单明了的Android代码破坏了我应用程序中的基本同步。

下面的方法总是立即执行,尽管事实上它有一个SQLiteDatabase.rawQuery()调用。 SQL查询花费多长时间都没关系:

// this method is always executed instantly,despite the rawQuery() call
private Cursor runRawQueryTest() {

    Log.i(TAG,"runRawQueryTest() started");
    long timer = System.currentTimeMillis();

    // SLOW_SQL_QUERY runs at least a couple seconds:
    Cursor c = getDb().rawQuery( SLOW_SQL_QUERY,null );

    timer = System.currentTimeMillis() - timer;
    // timer below always reports a few milliseconds:
    Log.i(TAG,"runRawQueryTest() finished in " + timer + "ms.");

    return c;
}

这是Logcat:

2020-10-06 23:57:07.609 ... I/MainActivity: runRawQueryTest() started
2020-10-06 23:57:07.621 ... I/MainActivity: runRawQueryTest() finished in 12ms. <<<< "incorrect" timer 

好像以某种方式内联了runRawQueryTest()方法。它本身不是问题(无论如何,谁在乎日志?),因为数据库查询实际上发生在调用runRawQueryTest()的方法中:

    public void onClick(View view) {
        long timer = System.currentTimeMillis();
        Log.i(TAG,"onClick()" );
        Cursor c = runRawQueryTest();
        //  database query actually happens here:
        Log.i(TAG,"cursor.getCount() " + c.getCount());
        if ( !c.isClosed() ) c.close();
        timer = System.currentTimeMillis() - timer;
        Log.i(TAG,"onClick() - done in " + timer + "ms. ");
    }

Logcat:

2020-10-06 23:57:07.609 ... I/MainActivity: onClick()
2020-10-06 23:57:07.609 ... I/MainActivity: runRawQueryTest() started
2020-10-06 23:57:07.621 ... I/MainActivity: runRawQueryTest() finished in 12ms.
2020-10-06 23:57:14.223 ... I/MainActivity: cursor.getCount() 1           <<<< actual query
2020-10-06 23:57:14.223 ... I/MainActivity: onClick() - done in 6614ms.   <<<< correct timer 

真正的问题是,在我的应用程序中,这些数据库调用是使用RxJava异步进行的。 rawQuery()包装在Observable中,如下所示:

// RxJava wrapper
public Single<Cursor> makeObservable(final String query) {
    return Single
            .fromCallable( () -> getCursorOrThrow(query) )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

您可能已经猜到了,Observable几乎立即发出一个项目,因此实际的SQL查询在onNext()调用之后运行。结果,主线程上进行了太多工作,UI混乱了,尤其是进度条。

如何确保rawQuery()方法同步执行?

我唯一的猜测是所有这些都是由于非理想的R8优化而发生的。但是我的项目具有非常标准的“开箱即用”设置。我试图解决问题,使用ProGuard的“ -dontoptimize”键并尝试使用不同的Gradle版本。不幸的是,它没有帮助。我的想法不多了。我在概念上做错了吗?非常感谢您的帮助!

要点: https://gist.github.com/DmitryOganezov/c52fd8fcfa4f5be3e6ae5016a6ef7b4d

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)