루퍼의 목적과 사용 방법은 무엇입니까?
저는 안드로이드가 처음입니다.그게 뭔지 알고 싶어요.Looper
클래스가 수행하는 작업 및 사용 방법.Android Looper 클래스 설명서를 읽었지만 완전히 이해할 수 없습니다.저는 여러 곳에서 그것을 보았지만 그것의 목적을 이해할 수 없었습니다.누가 나를 도와줄 수 있습니까? 목적을 정의해서.Looper
그리고 또한 가능하다면 간단한 예를 들 수 있습니까?
루퍼란 무엇입니까?
Looper는 대기열에서 메시지(실행 가능)를 실행하는 데 사용되는 클래스입니다.일반 스레드에는 이러한 대기열이 없습니다. 예를 들어 단순 스레드에는 대기열이 없습니다.메서드 실행이 완료된 후 스레드는 다른 메시지(실행 가능)를 실행하지 않습니다.
루퍼 클래스를 사용할 수 있는 곳은 어디입니까?
다른 사용자가 여러 메시지(실행 가능)를 실행하려면 스레드에서 대기열을 만드는 Looper 클래스를 사용해야 합니다.예를 들어 인터넷에서 파일을 다운로드하는 응용 프로그램을 작성하는 동안 Looper 클래스를 사용하여 다운로드할 파일을 대기열에 넣을 수 있습니다.
어떻게 작동합니까?
이 .prepare()
루퍼를 준비하는 방법.그러면 사용할 수 있습니다.loop()
현재 스레드에서 메시지 루프를 만드는 방법이며 루프를 종료할 때까지 Looper가 대기열에서 요청을 실행할 준비가 되었습니다.
여기 루퍼를 준비할 수 있는 코드가 있습니다.
class LooperThread extends Thread {
public Handler mHandler;
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
GUI 프레임워크의 맥락에서 Looper가 무엇인지 더 잘 이해할 수 있습니다.루퍼는 두 가지 일을 하도록 만들어졌습니다.
Looper는 Android 앱이 실행될 때까지 일반 스레드를 지속적으로 실행되는 스레드로 변환합니다.
Looper는 수행할 작업이 대기열에 있는 대기열을 제공합니다.
아시다시피, 응용 프로그램이 시작되면 시스템은 "메인"이라고 하는 응용 프로그램에 대한 실행 스레드를 생성하고 Android 응용 프로그램은 일반적으로 기본적으로 "메인 스레드" 하나에서만 실행됩니다.하지만 주 실은 비밀스러운 특별한 실이 아닙니다.이것은 당신이 만들 수 있는 것과 유사한 일반적인 스레드입니다.new Thread()
그것은 그것이 끝날 때 종료된다는 것을 의미합니다.run()
메서드가 반환됩니다!아래의 예를 생각해 보십시오.
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
이제 이 간단한 원리를 안드로이드 앱에 적용해 보겠습니다.안드로이드 앱이 일반 스레드에서 실행되면 어떻게 됩니까?"UI를 . """UI""라는 스레드입니다.따라서 첫 화면이 사용자에게 표시됩니다.그럼 어쩌라는 거야?주 스레드가 종료됩니까?아니요, 그러면 안 돼요.사용자가 뭔가를 할 때까지 기다려야 하는 거죠?하지만 우리는 어떻게 이런 행동을 할 수 있을까요?음, 우리는 시도할 수 있습니다.Object.wait()
또는Thread.sleep()
예를 들어 메인 스레드는 첫 화면을 표시하기 위한 초기 작업을 마치고 절전 모드로 전환됩니다.새 작업이 시작되면 중단됨을 의미하는 웨이크업 상태가 됩니다.아직까지는 좋지만, 현재로서는 여러 작업을 저장할 수 있는 대기열 같은 데이터 구조가 필요합니다.사용자가 화면을 연속적으로 터치하고 작업을 완료하는 데 더 오랜 시간이 걸리는 경우를 생각해 보십시오.따라서 선입선출 방식으로 작업을 수행할 수 있는 데이터 구조가 필요합니다.또한 인터럽트를 사용하여 항상 실행되고 프로세스 작업을 수행하는 스레드를 구현하는 것은 쉽지 않으며 복잡하고 종종 유지 관리가 불가능한 코드로 이어집니다.우리는 차라리 그러한 목적을 위한 새로운 메커니즘을 만들고 싶습니다. 그것이 바로 루퍼의 모든 것입니다.Looper 클래스의 공식 문서에는 "스레드에는 기본적으로 관련된 메시지 루프가 없습니다."라고 되어 있으며, Looper는 "스레드에 대한 메시지 루프를 실행하는 데 사용되는 클래스"입니다.이제 여러분은 그것이 무엇을 의미하는지 이해할 수 있습니다.
좀 더 명확하게 하기 위해, 메인 스레드가 변환되는 코드를 확인해 보겠습니다.모든 것은 활동에서 발생합니다.스레드 클래스.주() 메서드에서 아래 코드를 찾을 수 있습니다. 일반 스레드를 필요한 것으로 변환합니다.
public final class ActivityThread {
...
public static void main(String[] args) {
...
Looper.prepareMainLooper();
Looper.loop();
...
}
}
그리고.Looper.loop()
메소드는 무한 루프하고 메시지를 디큐하여 한 번에 하나씩 처리합니다.
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
}
}
기본적으로 Looper는 GUI 프레임워크에서 발생하는 문제를 해결하기 위해 만들어진 클래스입니다.하지만 이런 종류의 필요성은 다른 상황에서도 발생할 수 있습니다.사실, 이것은 멀티 스레드 애플리케이션에 꽤 유명한 패턴이며, Doug Lea의 "Java의 동시 프로그래밍"에서 더 자세히 배울 수 있습니다(특히 4.1.4장 "작업자 스레드"가 도움이 될 것입니다).또한 이러한 종류의 메커니즘은 Android 프레임워크에서 고유하지 않지만 모든 GUI 프레임워크는 다소 유사해야 할 수 있습니다.Java Swing 프레임워크에서도 거의 동일한 메커니즘을 찾을 수 있습니다.
Looper를 사용하면 단일 스레드에서 작업을 순차적으로 실행할 수 있습니다.그리고 핸들러는 우리가 실행해야 할 작업을 정의합니다.이 예에서 설명하려는 것은 일반적인 시나리오입니다.
class SampleLooper extends Thread {
@Override
public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();
// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
handler = new Handler();
// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
} catch (Throwable t) {
Log.e(TAG, "halted due to an error", t);
}
}
}
이제 다른 스레드(예: ui 스레드)의 핸들러를 사용하여 작업을 Looper에 게시하여 실행할 수 있습니다.
handler.post(new Runnable()
{
public void run() {
//This will be executed on thread using Looper.
}
});
UI 스레드에는 UI 스레드의 메시지를 처리할 수 있는 암묵적인 Looper가 있습니다.
안드로이드Looper
는 부할포입다니지를 입니다.MessageQueue
Thread
큐 처리를 관리합니다.Android 문서에서는 매우 암호화된 것으로 보이며 우리는 여러 번 직면할 수 있습니다.Looper
관련 UI 액세스 문제.우리가 기본적인 것을 이해하지 못하면 다루기가 매우 어려워집니다.
다음은 다음과 같은 설명을 하는 기사가 있습니다.Looper
라이프 사이클, 사용 방법 및 사용 방법Looper
Handler
루퍼 = 스레드 + 메시지 큐
루퍼 및 핸들러의 가장 간단한 정의:
루퍼는 스레드를 파이프라인 스레드로 변환하는 클래스이며 처리기는 다른 스레드에서 이 파이프로 작업을 밀어넣을 수 있는 메커니즘을 제공합니다.
일반적인 문구로 된 세부 정보:
파이프라인 스레드는 처리기를 통해 다른 스레드에서 더 많은 작업을 수신할 수 있는 스레드입니다.
Looper의 이름은 루프를 구현하기 때문입니다. 즉, 다음 작업을 수행하고 실행한 다음 다음 작업을 수행합니다.처리기는 다른 스레드에서 Looper(스레드 또는 파이프라인 스레드)로 전달될 때마다 다음 작업을 처리하거나 수락하는 데 사용되기 때문에 처리기라고 합니다.
예:
Looper 및 Handler 또는 PipeLine Thread의 가장 완벽한 예는 백그라운드에서 각 네트워크 호출에 대해 새 Thread를 시작하는 대신 하나 이상의 이미지를 다운로드하거나 단일 스레드에서 하나씩 서버(Http)에 업로드하는 것입니다.
Looper 및 Handler와 파이프라인 스레드의 정의에 대해 자세히 알아보십시오.
루퍼 스레드 이해
java 실행() 메서드에서 작업을 수행하고 그 후 종료하도록 설계된 실행 단위:
그러나 Android에서는 스레드를 유지하고 사용자 입력/이벤트를 기다려야 하는 많은 사용 사례가 있습니다.UI 스레드 어카Main Thread
.
Android의 메인 스레드는 JVM이 앱을 시작할 때 처음 시작하여 사용자가 닫기를 선택하거나 처리되지 않은 예외가 발생할 때까지 계속 실행되는 Java 스레드입니다.
응용 프로그램이 시작되면 시스템은 "메인"이라고 하는 응용 프로그램에 대한 실행 스레드를 만듭니다.이 스레드는 그리기 이벤트를 포함하여 적절한 사용자 인터페이스 위젯에 이벤트를 발송하는 역할을 담당하므로 매우 중요합니다.
여기서 주목해야 할 점은 메인 스레드가 Java 스레드이지만 사용자 이벤트를 계속 청취하고 화면에 60fps 프레임을 그리며 각 사이클이 끝난 후에도 죽지 않는다는 것입니다.왜 그럴까요?
정답은 Looper Class: Looper는 스레드를 활성 상태로 유지하고 메시지 큐를 관리하여 해당 스레드에서 작업을 실행하는 데 사용되는 클래스입니다.
스레드에는 기본적으로 메시지 루프가 연결되어 있지 않지만 실행 메서드에서 Looper.prepare()를 호출한 다음 Looper.loop()을 호출하여 메시지 루프를 할당할 수 있습니다.
입니다.
Message
계산을 수행할 개체입니다. 그렇지 않으면 첫 번째 실행 사이클 후에 삭제됩니다.
관리하는지 더 .Message
큐의 인 " 그 러 면 소 코 있 니 다 습 수 볼 를 드 스 ▁thenLooperclass
:
https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/Looper.java
은 다은생방예다입니법을 만드는 의 입니다.Looper Thread
을 해보세요.Activity
클스사용을 LocalBroadcast
class LooperThread : Thread() {
// sendMessage success result on UI
private fun sendServerResult(result: String) {
val resultIntent = Intent(ServerService.ACTION)
resultIntent.putExtra(ServerService.RESULT_CODE, Activity.RESULT_OK)
resultIntent.putExtra(ServerService.RESULT_VALUE, result)
LocalBroadcastManager.getInstance(AppController.getAppController()).sendBroadcast(resultIntent)
}
override fun run() {
val looperIsNotPreparedInCurrentThread = Looper.myLooper() == null
// Prepare Looper if not already prepared
if (looperIsNotPreparedInCurrentThread) {
Looper.prepare()
}
// Create a handler to handle messaged from Activity
handler = Handler(Handler.Callback { message ->
// Messages sent to Looper thread will be visible here
Log.e(TAG, "Received Message" + message.data.toString())
//message from Activity
val result = message.data.getString(MainActivity.BUNDLE_KEY)
// Send Result Back to activity
sendServerResult(result)
true
})
// Keep on looping till new messages arrive
if (looperIsNotPreparedInCurrentThread) {
Looper.loop()
}
}
//Create and send a new message to looper
fun sendMessage(messageToSend: String) {
//Create and post a new message to handler
handler!!.sendMessage(createMessage(messageToSend))
}
// Bundle Data in message object
private fun createMessage(messageToSend: String): Message {
val message = Message()
val bundle = Bundle()
bundle.putString(MainActivity.BUNDLE_KEY, messageToSend)
message.data = bundle
return message
}
companion object {
var handler: Handler? = null // in Android Handler should be static or leaks might occur
private val TAG = javaClass.simpleName
}
}
용도:
class MainActivity : AppCompatActivity() {
private var looperThread: LooperThread? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// start looper thread
startLooperThread()
// Send messages to Looper Thread
sendMessage.setOnClickListener {
// send random messages to looper thread
val messageToSend = "" + Math.random()
// post message
looperThread!!.sendMessage(messageToSend)
}
}
override fun onResume() {
super.onResume()
//Register to Server Service callback
val filterServer = IntentFilter(ServerService.ACTION)
LocalBroadcastManager.getInstance(this).registerReceiver(serverReceiver, filterServer)
}
override fun onPause() {
super.onPause()
//Stop Server service callbacks
LocalBroadcastManager.getInstance(this).unregisterReceiver(serverReceiver)
}
// Define the callback for what to do when data is received
private val serverReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val resultCode = intent.getIntExtra(ServerService.RESULT_CODE, Activity.RESULT_CANCELED)
if (resultCode == Activity.RESULT_OK) {
val resultValue = intent.getStringExtra(ServerService.RESULT_VALUE)
Log.e(MainActivity.TAG, "Server result : $resultValue")
serverOutput.text =
(serverOutput.text.toString()
+ "\n"
+ "Received : " + resultValue)
serverScrollView.post( { serverScrollView.fullScroll(View.FOCUS_DOWN) })
}
}
}
private fun startLooperThread() {
// create and start a new LooperThread
looperThread = LooperThread()
looperThread!!.name = "Main Looper Thread"
looperThread!!.start()
}
companion object {
val BUNDLE_KEY = "handlerMsgBundle"
private val TAG = javaClass.simpleName
}
}
대신 비동기 작업 또는 인텐트 서비스를 사용할 수 있습니까?
비동기 작업은 백그라운드에서 짧은 작업을 수행하고 UI 스레드에서 진행 및 결과를 제공하도록 설계되었습니다.비동기 작업에는 128개 이상의 비동기 작업을 생성할 수 없는 것과 같은 제한이 있습니다.
ThreadPoolExecutor
최대 5개의 비동기 작업만 허용합니다.IntentServices
더 할 수 있도록 할 수 .LocalBroadcast
의사소통을 하기 위해Activity
그러나 작업 실행 후 서비스가 파괴됩니다., 은 만당신그오랫실안동원행를기합당해다같니다검야은사를과 같은 .while(true){...}
.
루퍼 스레드의 다른 의미 있는 사용 사례:
서버가 클라이언트 소켓을 계속 청취하고 회신 확인을 하는 양방향 소켓 통신에 사용됩니다.
백그라운드에서 비트맵 처리 중입니다.이미지 URL을 Looper 스레드에 전달하면 필터 효과를 적용하여 임시 위치에 저장한 다음 이미지의 임시 경로를 브로드캐스트합니다.
Java 스레드의 수명은 다음 작업을 완료한 후에 종료됩니다.run()
수 .동일한 스레드를 다시 시작할 수 없습니다.
루퍼가 정상으로 변환합니다.Thread
메시지 루프로 이동합니다.의 주요 Looper
다음과 같습니다.
void prepare ()
현재 스레드를 루퍼로 초기화합니다.이렇게 하면 루프를 실제로 시작하기 전에 이 루퍼를 참조하는 핸들러를 만들 수 있습니다.이 메서드를 호출한 후 루프()를 호출해야 하며, quit()를 호출하여 종료해야 합니다.
void loop ()
이 스레드에서 메시지 대기열을 실행합니다.루프를 종료하려면 quit()를 호출해야 합니다.
void quit()
루프를 종료합니다.
메시지 큐에서 더 이상 메시지를 처리하지 않고 루프() 메서드를 종료합니다.
이 Janishar의 Mindorks 기사는 핵심 개념을 좋은 방식으로 설명합니다.
Looper
스레드와 연결되어 있습니다.이 필한경우가 필요하다면.Looper
스레드에서 UI 사용Looper.getMainLooper()
연결된 스레드를 반환합니다.
필요합니다Looper
처리기와 연결됩니다.
Looper
,Handler
,그리고.HandlerThread
비동기 프로그래밍의 문제를 해결하는 Android의 방법입니다.
일단 당신이 가지고 있는Handler
아래 API를 호출할 수 있습니다.
post (Runnable r)
Runnabler를 메시지 큐에 추가합니다.실행 테이블은 이 핸들러가 연결된 스레드에서 실행됩니다.
boolean sendMessage (Message msg)
현재 시간 전에 보류 중인 모든 메시지가 끝나면 메시지를 메시지 대기열 끝으로 밀어넣습니다.핸들 메시지(메시지), 이 핸들러에 연결된 스레드에서 수신됩니다.
HandlerThread는 루퍼가 있는 새 스레드를 시작하는 데 유용한 클래스입니다.그런 다음 루퍼를 사용하여 핸들러 클래스를 만들 수 있습니다.
시나리오에서는 를 실행할 수 .Runnable
의 작업( 네트워크 UI를 .InputStream
경우에는 이런경우는에,는,HandlerThread
유용합니다.얻을 수 있습니다.Looper
의 입니다.HandlerThread
다음을 생성하기Handler
HandlerThread
주 실 대신에
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
코드 예제는 아래 게시물을 참조하십시오.
루퍼가 가지고 있는 것은synchronized
MessageQueue
대기열에 저장된 메시지를 처리하는 데 사용됩니다.
은 구니다합현을다음을 합니다.Thread
특정 스토리지 패턴.
하나만.Looper
Thread
주요 방법은 다음과 같습니다.prepare()
,loop()
그리고.quit()
.
prepare()
전를초합니다화기를 합니다.Thread
Looper
.prepare()
이라static
를사는방법을 ThreadLocal
아래와 같이 등급을 지정합니다.
public static void prepare(){
...
sThreadLocal.set
(new Looper());
}
prepare()
이벤트 루프를 실행하기 전에 명시적으로 호출해야 합니다.loop()
특정 스레드의 메시지 큐에 메시지가 도착할 때까지 대기하는 이벤트 루프를 실행합니다.되면, 다메시수면되신가지음,,loop()
합니다.quit()
이벤트 루프를 종료합니다., 합니다.
Looper
할 수 .Thread
단계를
확다하
Thread
러
Looper.prepare()
를 스드로를초합니다화기레로 합니다.Looper
의 "" 를 합니다.
Handler
메시지를- 러
Looper.loop()
가 전달될 때까지 메시지를 처리합니다.quit()
.
이 답변은 질문과 아무런 관련이 없지만, 여기에 있는 모든 답변에서 루퍼의 사용과 사람들이 핸들러와 루퍼를 만든 방법은 명백한 잘못된 관행입니다(일부 설명은 옳지만), 저는 이것을 게시해야 합니다.
HandlerThread thread = new HandlerThread(threadName);
thread.start();
Looper looper = thread.getLooper();
Handler myHandler = new Handler(looper);
완벽한 구현을 위해
루퍼란 무엇입니까?
문서에서
Looper
에 대한 메시지 루프를 실행하는 데 사용되는 클래스thread
으로 스레드에는되어 있지 쓰레드를 를 호출하십시오. 쓰레드를 만들려면 를 호출하십시오.prepare()
루프를 에서 루를실는스에서드레, 고나서그리하.loop()
루프가 중지될 때까지 메시지를 처리하도록 합니다.
- A
Looper
처리루프입니다. - Looper의 중요한 특징은 Looper가 생성되는 스레드와 연관되어 있다는 것입니다.
- Looper 클래스는 목록 메시지를 포함하는 를 유지 관리합니다.Looper의 중요한 특징은 Looper가 생성되는 스레드와 연관되어 있다는 것입니다.
- 그
Looper
루프를 구현하기 때문에 이름이 붙여집니다. 즉, 다음 작업을 수행하고 실행한 다음 다음 작업을 수행합니다. 그Handler
가 더 나은 하지 못했기 . - 안드로이드
Looper
는 Android 사용자 인터페이스 내의 Java 클래스로, 버튼 클릭, 화면 재도면 및 방향 전환과 같은 UI 이벤트를 처리하는 핸들러 클래스와 함께 제공됩니다.
어떻게 작동합니까?
루퍼를 만드는 중
는 이실나를 .Looper
그리고 전화로Looper.prepare()
개봉 후에 Looper.prepare()
스레드를 하며 Looper와 Looper를 생성합니다.MessageQueue
시킵니다.
샘플 코드
class MyLooperThread extends Thread {
public Handler mHandler;
public void run() {
// preparing a looper on current thread
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
// this will run in non-ui/background thread
}
};
Looper.loop();
}
}
자세한 내용은 아래 게시물을 확인하십시오.
- 안드로이드에서 루퍼, 핸들러 및 메시지 큐는 어떤 관계입니까?
- Android 내장:루퍼 및 핸들러 소개
- Android Core 이해: 루퍼, 핸들러 및 핸들러실
- Android의 핸들러
- Android Looper란 무엇입니까?
- Android:루퍼, 핸들러, 핸들러실. 1부.
- Android의 MessageQueue 및 Looper
서비스에서 여러 다운로드 또는 업로드 항목을 처리하는 것이 더 좋은 예입니다.
Handler
그리고.AsnycTask
종종 UI(스레드)와 작업자 스레드 간에 이벤트/메시지를 전파하거나 작업을 지연시키는 데 사용됩니다.그래서 그들은 UI와 더 관련이 있습니다.
A Looper
에서는 사용자 상호 작용이나 표시된 UI가 없어도(앱이 통화 중에 백그라운드에서 파일을 다운로드함) 백그라운드의 스레드 관련 대기열에서 작업(실행 가능, 미래)을 처리합니다.
저는 루퍼 수업의 목적을 최대한 간단하게 설명하도록 노력하겠습니다.실행 방법이 실행을 완료할 때 일반적인 Java 스레드를 사용하면 스레드가 작업을 완료했으며 스레드는 더 이상 작동하지 않습니다.만약 우리가 프로그램 전체에 걸쳐 더 많은 작업을 더 이상 존재하지 않는 동일한 스레드로 실행하고 싶다면 어떻게 합니까?아, 지금 문제가 있는 거죠?예, 더 많은 작업을 실행하고 싶지만 스레드가 더 이상 활성화되지 않기 때문입니다.루퍼가 우리를 구하러 오는 곳입니다.이름이 루프를 암시하는 루퍼.루퍼는 스레드 내부의 무한 루프에 불과합니다.따라서 quit() 메서드를 명시적으로 호출할 때까지 스레드를 무한 시간 동안 유지합니다.무한 활성 스레드에서 quit() 메서드를 호출하면 스레드 내부의 무한 루프에서 조건이 거짓이 되므로 무한 루프가 종료됩니다.그래서, 실은 죽거나 더 이상 살아있지 않을 것입니다.그리고 루퍼가 부착된 스레드에서 quit() 메서드를 호출하는 것이 중요합니다. 그렇지 않으면 좀비처럼 시스템에 있을 것입니다.예를 들어, 백그라운드 스레드를 생성하여 여러 작업을 수행할 수 있습니다.우리는 간단한 자바의 스레드를 만들 것이고 Looper 클래스를 사용하여 루퍼를 준비하고 준비된 루퍼를 그 스레드와 함께 부착하여 우리의 스레드가 원하는 만큼 오래 살 수 있도록 할 것입니다. 왜냐하면 우리는 언제든지 스레드를 종료하고 싶을 때 quit()를 호출할 수 있기 때문입니다.따라서 루퍼는 스레드를 활성화하여 동일한 스레드로 여러 작업을 실행할 수 있으며 완료되면 quit()를 호출하여 스레드를 종료합니다.메인 스레드 또는 UI 스레드가 일부 UI 요소에서 백그라운드 스레드 또는 비 UI 스레드에 의해 계산된 결과를 표시하도록 하려면 어떻게 해야 합니까?이러한 목적을 위해 처리기의 개념이 있습니다. 처리기를 통해 프로세스 간 통신을 수행하거나 처리기를 통해 두 스레드가 서로 통신할 수 있습니다.따라서 메인 스레드에는 연결된 처리기가 있고 백그라운드 스레드는 해당 처리기를 통해 메인 스레드와 통신하여 메인 스레드의 일부 UI 요소에 계산된 결과를 표시하는 작업을 수행합니다.여기서 이론만 설명하는 것은 알지만 개념을 깊이 있게 이해하는 것이 매우 중요하기 때문에 개념을 이해하려고 노력합니다.그리고 루퍼, 핸들러, 핸들러에 관한 작은 비디오 시리즈로 안내하는 링크를 아래에 게시합니다.스레드와 저는 그것을 보는 것을 강력히 추천할 것이고 이 모든 개념들은 거기에 있는 예시들과 함께 지워질 것입니다.
https://www.youtube.com/watch?v=rfLMwbOKLRk&list=PL6nth5sRD25hVezlyqlBO9dafKMc5fAU2&index=1
저는 코틀린에서 예를 들어보려고 합니다.다음은 코드 예제입니다.
먼저 메인 스레드(Looper.getMainLooper())를 요청하는 Handler(기본 루퍼 대신 제공된 루퍼)의 변수 핸들러를 인스턴스화해야 합니다.
getAllCoures() 함수는 LiveData를 반환해야 하므로 handler.postDelayed()를 사용하여 메시지 큐에 추가하고 상수 SERVICE_LATency_IN_MILIS에 지정된 시간 x밀리초 후에 실행합니다.
좀 더 명확하게 하기 위해 제 설명에 자유롭게 더 많은 표현을 추가해 주시기 바랍니다.
class RemoteDataSource private constructor(private val jsonHelper: JsonHelper) {
private val handler = Handler(Looper.getMainLooper())
companion object {
private const val SERVICE_LATENCY_IN_MILLIS: Long = 2000
@Volatile
private var instance: RemoteDataSource? = null
fun getInstance(helper: JsonHelper): RemoteDataSource =
instance ?: synchronized(this) {
RemoteDataSource(helper).apply { instance = this }
}
}
fun getAllCourses(): LiveData<ApiResponse<List<CourseResponse>>> {
EspressoIdlingResource.increment()
val resultCourse = MutableLiveData<ApiResponse<List<CourseResponse>>>()
handler.postDelayed({
resultCourse.value = ApiResponse.success(jsonHelper.loadCourses())
EspressoIdlingResource.decrement()
}, SERVICE_LATENCY_IN_MILLIS)
return resultCourse
}
언급URL : https://stackoverflow.com/questions/7597742/what-is-the-purpose-of-looper-and-how-to-use-it
'sourcecode' 카테고리의 다른 글
각 행의 최대값이 있는 열 이름 찾기 (0) | 2023.06.18 |
---|---|
오류: HTTP 오류: 400, 프로젝트 'my_project'는 Firestore 지원 프로젝트가 아닙니다. (0) | 2023.06.18 |
Python 생성자 및 기본값 (0) | 2023.06.18 |
Angular 4에서 상위 구성 요소에서 하위 구성 요소로 데이터를 전달하는 방법 (0) | 2023.06.18 |
ZSH가 RVM__rvm_cleanse_variables에 대해 불만을 제기함: 함수 정의 파일을 찾을 수 없음 (0) | 2023.06.18 |