source

다른 스레드의 주 스레드에서 실행 중인 코드

goodcode 2022. 8. 3. 23:12
반응형

다른 스레드의 주 스레드에서 실행 중인 코드

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 스레드보다나은 입니다.

  1. 핸들러 작성스레드 및 시작
  2. 핸들러에서 Looper를 사용핸들러 작성스레드:requestHandler
  3. post a Runnable을 수행합니다.requestHandler

UI로부터의 HandlerThread

  1. 작성하다HandlerLooper스레드의 : " " " "responseHandler「」를 덮어씁니다.handleMessage
  2. Runnable다른 스레드의 태스크(HandlerThread 을 불러주세요.sendMessageresponseHandler
  3. ★★★★★★★★★★★★★★★★★.sendMessage「」의 결과 handleMessageresponseHandler.
  4. Attribute에서 .Message, UI 갱신

: 갱신TextView웹 서비스로부터 수신한 데이터를 사용합니다.는 UI 스레드로 할 필요가 에, 「UI」가 작성되었습니다.HandlerThread를 참조해 주세요. 스레드.메시지는 [UI 스레드(UI 스레드)]핸들러에 송신됩니다.HandlerUI를 사용하다

샘플 코드:

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);

유용한 기사:

핸들러 스레드 및 사용 이유

안드로이드루퍼루퍼슬레드i

가장 간단한 방법은 특히 컨텍스트가 없는 경우 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

반응형