UI 스레드의 처리기에 액세스해야하는 Android에서 새로운 것을 시도하고 있습니다.
다음을 알고 있습니다.
- UI 스레드에는 자체 처리기와 루 퍼가 있습니다.
- 모든 메시지는 UI 스레드의 메시지 대기열에 배치됩니다.
- 루퍼는 이벤트를 선택하여 핸들러에 전달합니다.
- 핸들러는 메시지를 처리하고 특정 이벤트를 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()
}
답변
해결책:
- 크리에이트 핸들러 와 루퍼 주 스레드에서을 : RequestHandler를을
- 만들기
Handler
와Looper
주 스레드에서 : ResponseHandler에와 재정의handleMessage
방법 - requestHandler에 실행 가능한 작업 게시
Runnable
태스크 내 에서 responseHandler에서 sendMessage를 호출하십시오.- 이
sendMessage
결과 responseHandler에서 handleMessage가 호출됩니다. - 에서 속성 가져 오기
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);
}
