web-dev-qa-db-ja.com

Androidの基本:UIスレッドでコードを実行する

UIスレッドでコードを実行するという観点では、次のような違いがあります。

MainActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

または

MainActivity.this.myView.post(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

そして

private class BackgroundTask extends AsyncTask<String, Void, Bitmap> {
    protected void onPostExecute(Bitmap result) {
        Log.d("UI thread", "I am the UI thread");
    }
}
413
Luky

それらのどれも正確に同じではありませんが、それらはすべて同じ正味の効果を持ちます。

1番目と2番目の違いは、コードの実行時に on メインアプリケーションスレッドになった場合、最初のスレッド(runOnUiThread())がすぐにRunnableを実行することです。 2番目のもの(post())は、すでにメインアプリケーションスレッドにいる場合でも、常にRunnableをイベントキューの最後に置きます。

3つ目は、BackgroundTaskのインスタンスを作成して実行すると仮定した場合、デフォルトで何もしないdoInBackground()を実行する前に、デフォルトのno-op post()を実行するためにスレッドプールからスレッドを取得するのに多くの時間を費やします。これは、3つのうち最も効率が悪い方法です。 onPostExecute()を使用するためだけでなく、バ​​ックグラウンドスレッドで実際に作業する必要がある場合は、AsyncTaskを使用します。

273
CommonsWare

HPP comment からのものが好きです。パラメータなしでどこでも使用できます。

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});
225
pomber

Handler を使う4番目の方法があります

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});
55
vasart

Pomberによる答えは受け入れ可能ですが、私は新しいオブジェクトを繰り返し作成することは大好きではありません。最善の解決策は、常にメモリ浪費を軽減しようとするものです。はい、自動ガベージコレクションがありますが、モバイルデバイスのメモリ節約はベストプラクティスの範囲内です。以下のコードは、サービス内のTextViewを更新します。

TextViewUpdater textViewUpdater = new TextViewUpdater();
Handler textViewUpdaterHandler = new Handler(Looper.getMainLooper());
private class TextViewUpdater implements Runnable{
    private String txt;
    @Override
    public void run() {
        searchResultTextView.setText(txt);
    }
    public void setText(String txt){
        this.txt = txt;
    }

}

それはこのようにどこからでも使用することができます。

textViewUpdater.setText("Hello");
        textViewUpdaterHandler.post(textViewUpdater);
18
Joe

Android PではgetMainExecutor()を使用できます。

getMainExecutor().execute(new Runnable() {
  @Override public void run() {
    // Code will run on the main thread
  }
});

Android開発者ドキュメント から::

このコンテキストに関連したメインスレッドでキューに入れられたタスクを実行するExecutorを返します。これは、アプリケーションコンポーネント(アクティビティ、サービスなど)への呼び出しをディスパッチするために使用されるスレッドです。

CommonsBlog から:

ContextでgetMainExecutor()を呼び出して、メインアプリケーションスレッドでジョブを実行するExecutorを取得できます。これを達成するには、LooperとカスタムExecutorの実装を使用して他の方法がありますが、これはより簡単です。

5
Dick Lucas

あなたがフラグメントで使用する必要がある場合は、使用する必要があります

private Context context;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;
    }


    ((MainActivity)context).runOnUiThread(new Runnable() {
        public void run() {
            Log.d("UI thread", "I am the UI thread");
        }
    });

の代わりに

getActivity().runOnUiThread(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

ページャーフラグメントのような状況ではnullポインタ例外が発生するため

5
Beyaz

こんにちはみんなこれは私が言う離れて基本的な質問です

ハンドラ を使用

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});
2
raghu kambaa