web-dev-qa-db-ja.com

Handler、Runnable、およびThreadsの違いは何ですか?

Handler、Runnable、およびThreadsの違いは何ですか?

Androidを使用していたときに、バックグラウンドで実行するものが必要です。スレッドを使用して実行します。通常、Threadを拡張するクラスを作成し、runメソッドを実装します。

また、runnableを実装してrunnableにThreadsに渡す例をいくつか見ました。

しかし、私はまだ混乱しています。誰かが明確な説明をくれますか?

  1. スレッドのrunメソッドでバックグラウンドコードを記述できる場合、Runnableのポイントは何ですか?
  2. ハンドラーはスレッド内でどのように使用され、なぜそれを使用する必要があるのですか。
  3. AndroidにはrunOnUiThreadという別の呼び出しがあります。これをどのように使用しますか? UIの更新に使用されることを知っています。
30
Hong Wei Wang

Runnable over Threadを使用する理由?

  • Runnableは、コードを実行するhowと非同期に実行する必要があるコードを分離します。これにより、コードの柔軟性が維持されます。たとえば、実行可能ファイル内の非同期コードは、スレッドプールまたは専用スレッドで実行できます。

    Threadには、実行可能ファイルにアクセスする必要がないと思われる状態があります。必要以上の状態にアクセスすることは、設計が不十分です。

    スレッドは多くのメモリを占有します。小さなアクションごとに新しいスレッドを作成すると、このメモリの割り当てと割り当て解除に処理時間がかかります。

runOnUiThreadは実際に何をしていますか?

  • Androidの runOnUiThread は、Runnableをキューに入れてUIスレッドで実行します。これは重要です。複数のスレッドからUIを更新しないでください。 runOnUiThreadHandlerを使用します。

    UIスレッドのキューがいっぱいであるか、実行が必要なアイテムが長い場合、キューに入れられたRunnableが実際に実行されるまでに時間がかかる場合があります。

ハンドラーとは?

  • ハンドラーを使用すると、特定のスレッドで実行する実行可能ファイルをポストできます。裏では、runOnUiスレッドがRunnableをAndroidのUiハンドラーのキューに入れ、runnableがUIスレッドで安全に実行できるようにします。
23

1。なぜ実行可能か?

Runnableは、スレッドをインスタンス化してそれを含めるために必要なインターフェースです。一方、スレッドにはすでにスレッドを生成する機能が含まれていますが、スレッドを拡張する場合、それ以外は拡張できません(Javaは多重継承をサポートしていません)。 1つのクラスに複数のインターフェイスを設定できるため、Runnableを設定できます。

また、Threadクラスを拡張すると、各スレッドが一意のオブジェクトを作成して関連付けます。 Runnableを実装すると、複数のスレッドで同じオブジェクトを共有します。

2。ハンドラーを使用する理由とは何ですか?

ハンドラーはJava(内部でスレッドを使用))で記述されているため、ハンドラーでできることはすべて、スレッドを使用しても実現できます。

では、なぜHandlerを使用する必要がありますか?理由は以下の通りです

  • ハンドラーを使用すると、スレッドのMessageQueueに関連付けられたMessageおよびRunnableオブジェクトを送信および処理できます。簡単に言えば、ハンドラーは仕事を簡単にします。

  • Androidには、スレッドを処理するための2つの主なルールがあります。

  • UIスレッドをブロックしないでください

  • UIスレッドの外部からAndroid UIツールキットにアクセスしないでください

上記の2つのルールでバインドするために、In Androidには、Activityクラスの1つが別のスレッドで実行されたり呼び出されたりする状況を処理できる3つの組み込みメソッドがあります。

次に、以下の3つの方法でUI更新をUIスレッドで実行するようにスケジュールできます。アクティビティまたはビューはハンドラーとして機能し(以下のハンドラーの詳細を参照)、UIスレッドに対して実行可能ファイルをスケジュールします。

  1. Activity.runOnUiThread(実行可能)
    1. View.post(実行可能)
    2. View.postDelayed(Runnable、long)//(long =スケジューリングまでの時間)

。UIスレッドとは?

UIスレッドは、ViewやActivityなどのUI要素がレンダリングされるメインスレッドです。時間のかかる操作は、UIスレッドでは発生しません。アプリケーションのデフォルトはUIスレッドで実行されます。 UIスレッドを使用するために特別なことをする必要はありません。

10
Prem

Handler、Runnable、およびThreadsは実際に連携して動作します。それらを比較する必要はないと思います。

ハンドラ

2つのスレッド間で安全にメッセージを送信できます。つまり、送信スレッドはメッセージを宛先スレッドキューに入れ、この宛先キューはこのメッセージを適切な時間に処理します。

実行可能

これは実装するインターフェイスです。実装では、実行するロジックをスレッドに配置します。 Runnableは、スレッドに関係のない場所でも実際に使用できます。多くのJava apiは実際にスレッドだけでなくRunnableを使用します。Runnableをハンドラーを使用して投稿するか、executorで使用できます。Runnableは、匿名実装の形式で実装できるため良いです。

ユニスレッド

あなたはUIスレッドを意味しましたか?ほとんどのユーザーインターフェイスは、すべてのUI要素であるウィンドウ/ウィジェットがメッセージを使用して通信します(ハンドラーと同様)。すなわち。ユーザーがボタンを押すと、ボタンが押されたという情報を含むメッセージが開始され、UIスレッドに送信され、最終的にリスナーに配信されます。

Android非UIスレッドからUI要素を変更することは禁止されています(例外が発生します)、これは理にかなっています-他のスレッドから変更する場合、UIスレッドがいくつかの変更を行っている間にこれが発生する可能性があります同じウィジェットに-未定義の動作になります。

4
marcinj

スレッドを使用して実行します。通常、Threadを拡張するクラスを作成し、runメソッドを実装します。

1.スレッドのrunメソッドでバックグラウンドコードを記述できる場合、Runnableのポイントは何ですか?

Runnableを使用し、Runnableからスレッドを作成することは一般的な習慣です。

Runnable Vs Thread使用法に関する 並行性 のOracleチュートリアルから:

Runnableオブジェクトはより一般的です。RunnableオブジェクトはThread以外のクラスをサブクラス化できるためです。

2.ハンドラーはスレッド内でどのように使用され、なぜ使用する必要があるのですか。

説明するのは広大なトピックです。公式文書サイトからの簡単な言葉で:

  1. ハンドラ を使用すると、スレッドのMessageに関連付けられたRunnableおよびMessageQueueオブジェクトを送信および処理できます。各Handlerインスタンスは、単一のスレッドとそのスレッドのメッセージキューに関連付けられています。

  2. 新しいHandlerを作成すると、それを作成しているスレッドのスレッド/メッセージキューにバインドされます-その時点から、メッセージと実行可能ファイルを配信しますメッセージキューから出て、それらを実行します。

  3. Handlerには主に2つの用途があります。(1)メッセージと実行可能ファイルを将来のある時点として実行するようにスケジュールするため。 (2)自分とは異なるスレッドで実行されるアクションをキューに入れる

  4. アプリケーション用にプロセスが作成されると、そのメインスレッドは、最上位のアプリケーションオブジェクト(アクティビティ、ブロードキャストレシーバーなど)およびそれらが作成するウィンドウを管理するメッセージキューの実行専用になります。 独自のスレッドを作成し、ハンドラーを介してメインアプリケーションスレッドとやり取りできます。これ以前と同じpostまたはsendMessageメソッドを呼び出しますが、新しいスレッドから呼び出します。指定されたRunnableまたはメッセージは、ハンドラーのメッセージキューでスケジュールされ、適切なときに処理されます。

blog.mindorks.com Anishar ALiの記事のこの図は、概念を明確に説明しています。

enter image description here

3. AndroidにはrunOnUiThreadという別の呼び出しがあります。これをどのように使用しますか? UIの更新に使用されることを知っています。

runOnUiThread の実装を調べると、詳細を確認できます。

/**
     * Runs the specified action on the UI thread. If the current thread is the UI
     * thread, then the action is executed immediately. If the current thread is
     * not the UI thread, the action is posted to the event queue of the UI thread.
     *
     * @param action the action to run on the UI thread
     */
    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

Handlerの使用例のコードについては、以下の投稿を参照してください。

Android:スレッドでトースト

1
Ravindra babu

スレッドのrunメソッドでバックグラウンドコードを記述できる場合、Runnableのポイントは何ですか?

Runnableは、Java.lang.Threadクラスを拡張して作成されたスレッドクラスに似た新しいスレッドクラスを作成するために使用されるインターフェイスです。唯一の違いは、Runnableインターフェイスにより、クラスが他のクラスを(必要に応じて)拡張して、あるクラスの機能をオーバーライド/継承できるようにすることです。 Java.lang.Threadクラスを拡張すると、この機能が無効になります。

また、Runnableインターフェースは、プレーンスレッドまたはエグゼキューターまたはその他の手段で実行できるタスクを表します。そのため、タスクをスレッドよりも実行可能として論理的に分離することは、設計上の適切な決定です。

詳細: http://javarevisited.blogspot.com/2012/01/difference-thread-vs-runnable-interface.html#ixzz2qgjDYJhT

0
Ankur Shanbhag

Runnable InterfaceはThread Classの親であり、run()はRunnable Interfaceのメソッドです。したがって、通常、クラスの動作を変更したくないため、別のクラスを拡張することもできるため、スレッドクラスの拡張よりもRunnableインターフェイスを優先する必要があります。疎結合を実現するだけでなく、ユーザーインターフェイスを他のクラスから変更するメリットもあります。

4つの方法でUiを変更できます

1.ハンドラーの例を使用して

public class MainActivity extends AppCompatActivity {    
private Handler mainHandler=new Handler();
class ExampleRunnable implements Runnable {
        int seconds;

        public ExampleRunnable(int seconds) {
            this.seconds = seconds;
        }

        @Override
        public void run() {
            for (int i = 0; i < seconds; i++) {
 mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                        button.setText("50% process completed");
                        }
                    });

2. runOnUIThread()を使用して、runOnUIThreadをpostにアタッチする必要があります。これは、例で簡単に理解できます。

class ExampleRunnable implements Runnable {
        int seconds;



 public ExampleRunnable(int seconds) {
        this.seconds = seconds;
    }

    @Override
    public void run() {runOnUIThread.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText(" Runnable");
                    }
                });
            }

3.任意のビューを使用して、ここで任意のビューで呼び出すことができます

public class MainActivity extends AppCompatActivity {
 private Switch aSwitch;
@Override
    protected void onCreate(Bundle savedInstanceState) {
 aSwitch=findViewById(R.id.switch1);
class ExampleRunnable implements Runnable {
            int seconds;



     public ExampleRunnable(int seconds) {
            this.seconds = seconds;
        }

        @Override
        public void run() { aSwitch.post(new Runnable() {
                        @Override
                        public void run() {
                            button.setText(" Runnable");
                        }
                    });
                }

4.別のスレッドでハンドラを作成することにより、デフォルトでスレッドルーパーにアタッチするため、ルーパーを定義する必要があります

Handler threadHandler=new Handler(Looper.getMainLooper());
threadHandler.post(new Runnable()
{
                            @Override
                            public void run() {
                                button.setText(" Runnable");
                            }
                        });
                    }

これは実装の4つの方法であるため、実行可能なスレッドとrunOnUIThread()について何かができると思います。Handlerは他の人によって美しく書かれています。

0
Harshit Joshi