2

アクティビティから新しいスレッドを開始しています。このスレッドは 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 がまだ応答しません

4

2 に答える 2