다른 스레드의 주 스레드에서 실행 중인 코드
Android 서비스에서는 백그라운드 작업을 수행하기 위한 스레드를 만들었습니다.
스레드가 메인 스레드의 메시지 큐에 특정 태스크를 게시해야 하는 상황이 발생한 경우(예:Runnable
.
어떻게 할 수 있을까요?Handler
주요 실과 기둥의Message
/Runnable
내 다른 실에서 나온거야?
메모: 이 답변은 많은 관심을 끌었기 때문에 업데이트해야 합니다.@dzeikei로부터의 코멘트는, 오리지날의 코멘트와 거의 같은 주목을 받고 있다.다음으로 생각할 수 있는2가지 해결책을 제시하겠습니다.
1. 배경 스레드에 참조가 있는 경우Context
오브젝트:
백그라운드 워커 스레드가 컨텍스트개체(어플리케이션콘텍스트 또는 서비스콘텍스트)에 액세스 할 수 있는 것을 확인합니다.다음으로 백그라운드워커 스레드로 다음 작업을 수행합니다.
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
2. 백그라운드 스레드에 다음이 없는 경우(또는 필요한 경우)Context
물건
(@dzeikei에 의해 설명):
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
아래의 코멘트가 올바르게 지적한 바와 같이, 이것은 일반적인 서비스의 솔루션이 아닙니다.고객의 활동으로부터 기동하는 스레드(서비스는 그러한 스레드일 수 있지만, 모든 것이 그러한 것은 아닙니다)에 한정됩니다.서비스 액티비티 커뮤니케이션의 복잡한 토픽에 대해서는 공식 문서의 서비스 섹션 전체를 읽어주세요.복잡하기 때문에 기본을 이해하면 도움이 됩니다.http://developer.android.com/guide/components/services.html#Notifications
다음 방법은 가장 간단한 경우에 사용할 수 있습니다.
제가 제대로 이해한 경우 애플리케이션의 GUI 스레드에서 실행할 코드가 필요합니다('메인' 스레드라고 불리는 다른 것은 생각할 수 없습니다).이를 위한 방법이 있다.Activity
:
someActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
}//public void run() {
});
문서: http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
이것이 당신이 찾고 있는 것이기를 바랍니다.
코틀린 버전
액티비티를 하고 있는 경우는,
runOnUiThread {
//code that runs in main
}
액티비티 컨텍스트가 있는 경우 mContext는
mContext.runOnUiThread {
//code that runs in main
}
사용할 수 있는 컨텍스트가 없는 장소에 있는 경우
Handler(Looper.getMainLooper()).post {
//code that runs in main
}
콘텍스트에 액세스 할 수 없는 경우는, 다른 간단한 방법이 있습니다.
1) 메인 looper에서 핸들러를 만듭니다.
Handler uiHandler = new Handler(Looper.getMainLooper());
2) Runnable 인터페이스를 구현합니다.
Runnable runnable = new Runnable() { // your code here }
3) 실행 가능 파일을 uiHandler에 게시합니다.
uiHandler.post(runnable);
이상입니다;-) 스레드를 즐기면서 동기화하는 것을 잊지 마십시오.
액션을시키는 등의 스레드에서 , "Delaying"을 호출해야 .runOnUiThread
맥상상문를 들어,가 「」의 내부에 는, 「」입니다.MainActivity
class는class를 사용합니다.
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
myAction();
}
});
메인(UI 스레드) 또는 다른 스레드에서 메서드를 호출할 수 있는 경우 다음과 같은 체크가 필요합니다.
public void myMethod() {
if( Looper.myLooper() == Looper.getMainLooper() ) {
myAction();
}
else {
}
요약 코드 블록은 다음과 같습니다.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// things to do on the main thread
}
});
액티비티 레퍼런스나 어플리케이션 레퍼런스를 건네주는 것은 아닙니다.
Kotlin 동등품:
Handler(Looper.getMainLooper()).post(Runnable {
// things to do on the main thread
})
HandlerThread
는 Android의 Java 스레드보다나은 입니다.
UI로부터의 HandlerThread
- 작성하다
Handler
Looper
스레드의 : " " " "responseHandler
「」를 덮어씁니다.handleMessage
Runnable
다른 스레드의 태스크(HandlerThread
을 불러주세요.sendMessage
responseHandler
- ★★★★★★★★★★★★★★★★★.
sendMessage
「」의 결과handleMessage
responseHandler
. - Attribute에서 .
Message
, UI 갱신
예: 갱신TextView
웹 서비스로부터 수신한 데이터를 사용합니다.는 UI 스레드로 할 필요가 에, 「UI」가 작성되었습니다.HandlerThread
를 참조해 주세요. 스레드.메시지는 [UI 스레드(UI 스레드)]핸들러에 송신됩니다.Handler
UI를 사용하다
샘플 코드:
HandlerThread handlerThread = new HandlerThread("NetworkOperation");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
txtView.setText((String) msg.obj);
}
};
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Runnable", "Before IO call");
URL page = new URL("http://www.your_web_site.com/fetchData.jsp");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ((line = buff.readLine()) != null) {
text.append(line + "\n");
}
Log.d("Runnable", "After IO call:"+ text.toString());
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
유용한 기사:
가장 간단한 방법은 특히 컨텍스트가 없는 경우 RxAndroid를 사용하는 경우 다음과 같은 작업을 수행할 수 있습니다.
AndroidSchedulers.mainThread().scheduleDirect {
runCodeHere()
}
핸들러를 사용한 보다 정확한 Kotlin 코드:
Handler(Looper.getMainLooper()).post {
// your codes here run on main Thread
}
생각할 수 있는 한 가지 방법은 다음과 같습니다.
UI를 .1) UI를 사용합니다.
2) ㄴㄴㄴㄴㄴ데 보이다.Binder
해 주세요.Handler
:
public void registerHandler(Handler handler) {
mHandler = handler;
}
3) UI 스레드에서 서비스에 바인드한 후 위의 메서드를 호출합니다.
mBinder.registerHandler(new Handler());
4) 서비스 스레드의 핸들러를 사용하여 작업을 게시합니다.
mHandler.post(runnable);
오래된 질문인 것은 알지만, Kotlin과 Java 모두에서 사용하는 주요 스레드 원라이너를 발견했습니다.이것은 서비스에 최적인 솔루션은 아닐지도 모르지만, fragment내의 UI 를 변경하는 것을 호출하는 경우는, 지극히 심플하고 명백합니다.
자바(8):
getActivity().runOnUiThread(()->{
//your main thread code
});
코틀린:
this.runOnUiThread {
//your main thread code
}
가장 편리한 것은 다음과 같은 것입니다.
import android.os.AsyncTask
import android.os.Handler
import android.os.Looper
object Dispatch {
fun asyncOnBackground(call: ()->Unit) {
AsyncTask.execute {
call()
}
}
fun asyncOnMain(call: ()->Unit) {
Handler(Looper.getMainLooper()).post {
call()
}
}
}
그 후:
Dispatch.asyncOnBackground {
val value = ...// super processing
Dispatch.asyncOnMain { completion(value)}
}
이 방법을 따르세요.이 방법을 사용하면 백그라운드 스레드에서 UI를 간단히 업데이트할 수 있습니다.runOnUiThread는 메인(UI) 스레드에서 작동합니다.이 코드 스니펫은 특히 초보자에게 덜 복잡하고 쉽다고 생각합니다.
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//code you want to run on the background
someCode();
//the code you want to run on main thread
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
/*the code you want to run after the background operation otherwise they will executed earlier and give you an error*/
executeAfterOperation();
}
});
}
});
서비스의 경우
작성 시 핸들러를 작성하다
handler = new Handler();
그럼 이렇게 쓰세요.
private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}
ContextCompat.getMainExecutor(context).execute {
// do something
}
Kotlin의 경우 Anko Corountines를 사용할 수 있습니다.
갱신하다
doAsync {
...
}
권장되지 않다
async(UI) {
// Code run on UI thread
// Use ref() instead of this@MyActivity
}
public void mainWork() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//Add Your Code Here
}
});
}
이것은 서비스 클래스에서도 문제없이 동작할 수 있습니다.
Kotlin을 사용하면 다음과 같은 기능을 사용할 수 있습니다.
runOnUiThread {
// Do work..
}
언급URL : https://stackoverflow.com/questions/11123621/running-code-in-main-thread-from-another-thread
'source' 카테고리의 다른 글
루트에 근거한 조건부 상태 (0) | 2022.08.03 |
---|---|
vuejs는 상위 구성 요소에서 하위 구성 요소로 모델을 전달하고 변환을 허용합니다. (0) | 2022.08.03 |
vuex를 사용하여 항목을 삭제하는 방법 (0) | 2022.08.03 |
POSIX 소켓을 플러시하는 방법이 있습니까? (0) | 2022.08.03 |
'안드로이드'를 어떻게 고치죠?Network On Main Thread Exception'? (0) | 2022.08.03 |