web-dev-qa-db-ja.com

サービスからUIスレッドハンドラーにアクセスする

私はUIスレッドのハンドラーにアクセスする必要があるAndroidで新しいことを試みています。

私は次のことを知っています:

  1. UIスレッドには独自のハンドラーとルーパーがあります
  2. すべてのメッセージはUIスレッドのメッセージキューに入れられます
  3. ルーパーはイベントを取得し、ハンドラーに渡します
  4. ハンドラーはメッセージを処理し、特定のイベントをUIに送信します

UIスレッドハンドラーを取得し、このハンドラーにメッセージを挿入する必要があるサービスが必要です。そのため、このメッセージは処理され、UIに発行されます。ここでは、サービスは、何らかのアプリケーションによって開始される通常のサービスになります。

これが可能かどうか知りたいです。もしそうなら、私はそれを試すことができるように、いくつかのコードスニペットを提案してください。

よろしくGirish

87
iLikeAndroid

このコードスニペットは、メイン(UI)スレッドに関連付けられたハンドラーを構築します。

Handler handler = new Handler(Looper.getMainLooper());

その後、次のようにメイン(UI)スレッドに実行用のものを投稿できます。

handler.post(runnable_to_call_from_main_thread);

ハンドラー自体がメイン(UI)スレッドから作成される場合、簡潔にするために引数を省略できます。

Handler handler = new Handler();

プロセスとスレッドの Android Dev Guide に詳細があります。

173
volley

MessengerにアタッチされたHandlerオブジェクトを作成し、そのMessengerServiceに渡します(たとえば、startService())。 Serviceは、Messageを介してHandlerMessengerを送信できます。 これはサンプルアプリケーションです これを示しています。

28
CommonsWare

現時点では、この種の問題には Otto などのイベントバスライブラリを使用することを好みます。目的のコンポーネント(アクティビティ)をサブスクライブするだけです。

protected void onResume() {
    super.onResume();
    bus.register(this);
}

次に、コールバックメソッドを提供します。

public void onTimeLeftEvent(TimeLeftEvent ev) {
    // process event..
}

そして、サービスが次のようなステートメントを実行するとき:

bus.post(new TimeLeftEvent(340));

そのPOJOは、上記のアクティビティと他のすべてのサブスクライブコンポーネントに渡されます。シンプルでエレガント。

4
pram

ブロードキャストレシーバーを介して値を取得できます......次のように、まず独自のIntentFilterを作成し、

Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");

次に、内部クラスBroadcastReceiverを次のように作成します。

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    /** Receives the broadcast that has been fired */
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction()=="YOUR_INTENT_FILTER"){
           //HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
           String receivedValue=intent.getStringExtra("KEY");
        }
    }
};

次に、onResume()でブロードキャストレシーバを次のように登録します。

registerReceiver(broadcastReceiver, intentFilter);

最後に、onDestroy()でBroadcastReceiverの登録を解除します。

unregisterReceiver(broadcastReceiver);

ここで最も重要な部分...値を送信する必要がある場所からブロードキャストを起動する必要があります。

Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);

.... cheers :)

2
Melbourne Lopes

次のコードを試すことをお勧めします。

    new Handler(Looper.getMainLooper()).post(() -> {

        //UI THREAD CODE HERE



    });
0
user2983041

kotlinでは、それがどのようにできるのか

サービスからのトーストメッセージを表示する場合は発言しましょう

val handler = Handler(Looper.getMainLooper())
handler.post {
   Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}
0
Zohab Ali

解決:

  1. メインスレッドから LooperHandler を作成します:requestHandler
  2. メインスレッドからのHandlerを使用してLooperを作成します:responseHandlerおよびhandleMessageメソッドをオーバーライドします
  3. requestHandlerに Runnable タスクを投稿します
  4. Runnableタスク内で、responseHandlerでsendMessageを呼び出します
  5. このsendMessage結果は、responseHandlerのhandleMessageの呼び出しを行います。
  6. Messageから属性を取得して処理し、UIを更新します

サンプルコード:

    /* Handler from UI Thread to send request */

    Handler requestHandler = new Handler(Looper.getMainLooper());

     /* Handler from UI Thread to process messages */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {

            /* Processing handleMessage */

            Toast.makeText(MainActivity.this,
                    "Runnable completed with result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    for ( int i=0; i<10; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                   /* Send an Event to UI Thread through message. 
                      Add business logic and prepare message by 
                      replacing example code */

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }
0
Ravindra babu