アクティビティから新しいスレッドを開始しています。このスレッドは 10 秒の操作を実行し、UI に次のように報告します。runOnUiThread()
10 秒間の操作の間、UI が応答しなくなり、ユーザーの操作に応答しなくなります。この場合、ツールバーのボタンを使用してアクティビティを閉じようとしています。ANRエラーがスローされますが、ボタンのクリックはワーカー スレッドの終了後に処理されます。
ProgressBar
ただし、スレッドが動作している間、UI スレッドで作業が行われている場合には発生しない回転をアプリで表示できます。
は、このProfiler
作業中に UI スレッドがスリープしていることを示しています。代わりに使用してみましAsyncTask
たが、それも機能しません。とにかく、ここにいくつかのコードがあります:
Thread
ウィンドウがフォーカスされると、新しいものが開始されます。
アクティビティ:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus && !recyclerSetup){
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.VISIBLE);
WorkThread thread = new WorkThread();
thread.start();
}
}
スレッド:
private class WorkThread extends Thread {
@Override
public void run() {
getViewModelAndWords();
runOnUiThread(() -> setupRecycler());
}
}
private void getViewModelAndWords() {
viewModel = ViewModelProviders.of(this).get(WordViewModel.class);
adapter = new WordDetailedAdapter(this, viewModel, this, this, !favGroup.equals(ANY_WORD_PARAM));
allWords = viewModel.getAllWords();
}
viewModel
問題と関係があるかどうかはわかりませんviewModel.getAllWords()
が、重い 10 秒の Room db 操作を実行するメソッドです。
スリープ状態のUI スレッドとワーカー(AsyncTask #6)Profiler
を示すスナップショットを次に示します。Thread
編集:
わかりましたので、問題は部屋の DB 操作にあると思います / viewModel
. のコンテンツを置き換えると、getAllWords()
ユーザーThread.sleep(10000);
の操作のために UI スレッドが解放されるため、(何らかの理由で) ユーザー入力を妨げているのは次のコードです。
編集2:
提案されているように、私は今onPostExecute()
、単語を取得するためにインターフェースと共に使用しています:
public static class GetAllWordsWithCallBackTask extends AsyncTask<Void, Void, List<Word>>{
WordViewModel.iGetWords listener;
WordDao wordDao;
public GetAllWordsWithCallBackTask(WordDao wordDao, WordViewModel.iGetWords listener) {
this.listener = listener;
this.wordDao = wordDao;
}
@Override
protected List<Word> doInBackground(Void... voids) {
return wordDao.getAllWords();
}
@Override
protected void onPostExecute(List<Word> words) {
listener.gotWords(words);
}
}
get()
listener
は削除され、コールバックを処理するために渡してタスクを実行するだけです。
public void getAllWordsWithCallBack(WordViewModel.iGetWords listener) {
try {
new GetAllWordsWithCallBackTask(wordDao, listener).execute();
} catch (Exception e) {
Crashlytics.log("Getting all words exception: "+e.getMessage());
e.printStackTrace();
}
}
これはうまく機能し、単語はアクティビティに正常に返されますが、操作の実行中は UI がまだ応答しません。