AsyncTask完成,但活动UI超过20秒未更新

时间:2018-12-07 19:10:11

标签: java android

我有一个用于查询数据库的AsyncTask,但是更新UI可能需要20秒钟以上。起初我以为这是数据库查询的速度很慢,但是在输入一些调试语句之后,事实证明所有操作实际上都非常快。 onPostExecute中的最后一条指令完成,然后20秒钟以上,UI最终更新。这是在运行Android 9 Pie的手机上发生的,在早期版本中,它的运行速度要快得多。为什么会这样呢?可能会发生什么? 编辑:在运行Android 7的手机上,大约需要2秒钟。

void callBackgroundQuery(String query){
    backgroundQuery BQ = new backgroundQuery(this);
    BQ.execute(query);
}

private class backgroundQuery extends AsyncTask<String, Void, String>{
    private ReadingActivity mReadingActivity;

    public backgroundQuery(ReadingActivity ra){
        mReadingActivity = ra;
    }

    @Override
    protected String doInBackground(String... query) {
        System.out.println("Getting DB Instance");
        SQLiteDatabase db = mDbHelper.getInstance(getApplicationContext()).getReadableDatabase();
        System.out.println("Querying DB");
        Cursor c = db.rawQuery(query[0],null);
        StringBuilder builder = new StringBuilder();
        String chap, verse, text;
        int bookNum;
        System.out.println("Moving to first and parsing lines");
        c.moveToFirst();
        while (!c.isAfterLast()) {
            bookNum = c.getInt(0);
            chap = c.getString(1);
            verse = c.getString(2);
            text = c.getString(3);
            String completeVerse = getAbbreviation(bookNum) + " " + chap + ":" + verse + " " + text;
            builder.append(completeVerse).append("\n");
            c.moveToNext();
        }
        System.out.println("Finished parsing, starting builder.toString()");
        String completeText = builder.toString();
        System.out.println("Finished building string, returning and setting text");
        return completeText;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        System.out.println("Setting text");
        mTextView.setText(result);
        System.out.println("Setting scroll");
        mReadingActivity.setScroll();
        // This outputs, and 20+ seconds later the TextView displays the text
        System.out.println("Finished setting scroll");
    }
}

1 个答案:

答案 0 :(得分:1)

要解决Android Pie缓慢的setText问题,我根据注释中的建议使用了PrecomputedText。我根据SDK版本创建了单独的AsyncTask类供使用。我不知道是否有更好的方法来处理该部分,但真正的解决方案是通过在Android 9中使用PrecomputedText来解决。

void callBackgroundQuery(String query){
    if (android.os.Build.VERSION.SDK_INT >= 28){
        backgroundQueryAPI28 BQ = new backgroundQueryAPI28(this);
        BQ.execute(query);
    } else {
        backgroundQuery BQ = new backgroundQuery(this);
        BQ.execute(query);
    }
}

private class backgroundQueryAPI28 extends AsyncTask<String, Void, PrecomputedText>{
    private ReadingActivity mReadingActivity;

    final PrecomputedText.Params params = mTextView.getTextMetricsParams();
    final Reference textViewRef = new WeakReference<>(mTextView);

    public backgroundQueryAPI28(ReadingActivity ra){
        mReadingActivity = ra;
    }

    @Override
    protected PrecomputedText doInBackground(String... query) {
        SQLiteDatabase db = mDbHelper.getInstance(getApplicationContext()).getReadableDatabase();
        Cursor c = db.rawQuery(query[0],null);
        StringBuilder builder = new StringBuilder();
        String chap, verse, text;
        int bookNum;
        c.moveToFirst();
        while (!c.isAfterLast()) {
            bookNum = c.getInt(0);
            chap = c.getString(1);
            verse = c.getString(2);
            text = c.getString(3);
            String completeVerse = getAbbreviation(bookNum) + " " + chap + ":" + verse + " " + text;
            builder.append(completeVerse).append("\n");
            c.moveToNext();
        }

        String allText = builder.toString();
        final PrecomputedText precomputedText = PrecomputedText.create(allText, params);
        return precomputedText;
    }

    @Override
    protected void onPostExecute(PrecomputedText result) {
        super.onPostExecute(result);
        mTextView.setText(result);
        mReadingActivity.setScroll();
    }
}

private class backgroundQuery extends AsyncTask<String, Void, String>{
    private ReadingActivity mReadingActivity;

    public backgroundQuery(ReadingActivity ra){
        mReadingActivity = ra;
    }

    @Override
    protected String doInBackground(String... query) {
        SQLiteDatabase db = mDbHelper.getInstance(getApplicationContext()).getReadableDatabase();
        Cursor c = db.rawQuery(query[0],null);
        StringBuilder builder = new StringBuilder();
        String chap, verse, text;
        int bookNum;
        c.moveToFirst();
        while (!c.isAfterLast()) {
            bookNum = c.getInt(0);
            chap = c.getString(1);
            verse = c.getString(2);
            text = c.getString(3);
            String completeVerse = getAbbreviation(bookNum) + " " + chap + ":" + verse + " " + text;
            builder.append(completeVerse).append("\n");
            c.moveToNext();
        }

        String allText = builder.toString();
        return allText;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        mTextView.setText(result);
        mReadingActivity.setScroll();
    }
}