我有一个用于查询数据库的 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");
}
}
最佳答案
为了解决 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();
}
}
关于java - AsyncTask 完成,但 Activity UI 未更新超过 20 秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53675515/