[android] 서비스에서 UI 스레드 처리기에 액세스

UI 스레드의 처리기에 액세스해야하는 Android에서 새로운 것을 시도하고 있습니다.

다음을 알고 있습니다.

  1. UI 스레드에는 자체 처리기와 루 퍼가 있습니다.
  2. 모든 메시지는 UI 스레드의 메시지 대기열에 배치됩니다.
  3. 루퍼는 이벤트를 선택하여 핸들러에 전달합니다.
  4. 핸들러는 메시지를 처리하고 특정 이벤트를 UI로 보냅니다.

UI 스레드 처리기를 가져 와서이 처리기에 메시지를 넣어야하는 서비스를 갖고 싶습니다. 이 메시지가 처리되어 UI에 발행되도록합니다. 여기서 서비스는 일부 응용 프로그램에서 시작되는 일반 서비스입니다.

이것이 가능한지 알고 싶습니다. 그렇다면 시도해 볼 수 있도록 몇 가지 코드 스 니펫을 제안하십시오.

감사합니다 Girish



답변

이 코드 스 니펫은 기본 (UI) 스레드와 연관된 핸들러를 구성합니다.

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

그런 다음 다음과 같이 기본 (UI) 스레드에서 실행할 항목을 게시 할 수 있습니다.

handler.post(runnable_to_call_from_main_thread);

핸들러 자체가 메인 (UI) 스레드에서 생성 된 경우 간결성을 위해 인수를 생략 할 수 있습니다.

Handler handler = new Handler();

프로세스 및 스레드에 대한 Android 개발자 가이드 에 자세한 정보가 있습니다.


답변

Messenger첨부 된 개체를 Handler만들고에 전달 Messenger합니다 Service(예 :에 대한 Intent추가 startService()). 는 Service다음을 보낼 수 있습니다 Message받는 Handler비아 Messenger. 다음은이를 보여주는 샘플 애플리케이션 입니다.


답변

현재 나는 이런 종류의 문제에 오토 와 같은 이벤트 버스 라이브러리를 사용하는 것을 선호합니다 . 원하는 구성 요소 (활동)를 구독하기 만하면됩니다.

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

그런 다음 콜백 메서드를 제공합니다.

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

그런 다음 서비스가 다음과 같은 문을 실행할 때 :

bus.post(new TimeLeftEvent(340));

해당 POJO는 위의 활동 및 기타 모든 구독 구성 요소에 전달됩니다. 간단하고 우아합니다.


답변

다음 코드를 시도해 보는 것이 좋습니다.

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

        //UI THREAD CODE HERE



    });


답변

다음과 같이 브로드 캐스트 수신기를 통해 값을 얻을 수 있습니다. 먼저 고유 한 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);

…. 건배 🙂


답변

에서 kotlin그게 당신이 그것을 할 수있는 방법

서비스에서 토스트 메시지를 표시하려면

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


답변

해결책:

  1. 크리에이트 핸들러루퍼 주 스레드에서을 : RequestHandler를을
  2. 만들기 HandlerLooper주 스레드에서 : ResponseHandler에와 재정의 handleMessage방법
  3. requestHandler에 실행 가능한 작업 게시
  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);
    }