IT

정의된 간격으로 Android에서 실행 가능한 스레드를 실행하는 방법은 무엇입니까?

itgroup 2023. 8. 6. 09:58
반응형

정의된 간격으로 Android에서 실행 가능한 스레드를 실행하는 방법은 무엇입니까?

나는 안드로이드 에뮬레이터 화면에 정의된 간격으로 텍스트를 표시하는 앱을 개발했습니다.사용 중입니다.Handler다음은 제 코드의 일부입니다.

handler = new Handler();
Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");               
    }
};
handler.postDelayed(r, 1000);

이 응용 프로그램을 실행하면 텍스트가 한 번만 표시됩니다. 이유는 무엇입니까?

예제의 간단한 해결 방법은 다음과 같습니다.

handler = new Handler();

final Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");
        handler.postDelayed(this, 1000);
    }
};

handler.postDelayed(r, 1000);

또는 일반 스레드를 사용할 수 있습니다(원래 Runner 사용).

Thread thread = new Thread() {
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                handler.post(this);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

thread.start();

실행 가능한 개체는 실행을 위해 메시지 대기열로 보낼 수 있는 명령으로 간주하고 처리기는 해당 명령을 보내는 데 사용되는 도우미 개체로 간주할 수 있습니다.

자세한 내용은 http://developer.android.com/reference/android/os/Handler.html 를 참조하십시오.

new Handler().postDelayed(new Runnable() {
    public void run() {
        // do something...              
    }
}, 100);

매초 업데이트를 위해 알렉스2k8의 첫 번째 솔루션을 개선할 수 있다고 생각합니다.

1. 원본 코드:

public void run() {
    tv.append("Hello World");
    handler.postDelayed(this, 1000);
}

2.분석

  • 위의 비용으로 가정해 보겠습니다.tv.append("Hello Word")비용 T밀리초, 표시 후 500회 지연 시간은 500*T밀리초입니다.
  • 장시간 실행 시 지연 증가합니다.

해결책

PostDelayed()의 순서만 변경하지 않으려면 지연을 방지하려면 다음을 수행합니다.

public void run() {
    handler.postDelayed(this, 1000);
    tv.append("Hello World");
}

반복 작업에 사용할 수 있습니다.

new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);

과 같이 여기다

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

            }
        },500,1000);

위의 코드는 0.5초 후에 처음 실행되고(500) 매초 후에 반복됩니다(1000).

어디에

태스크는 실행할 메서드입니다.

최초 실행 시간 후에.

(실행을 반복하기 위한 시간 계산)

두번째로

또한 작업 횟수를 실행하려는 경우 CountDownTimer를 사용할 수도 있습니다.

    new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval

     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
     }
    }.start();

//Above codes run 40 times after each second

또한 runnable로도 할 수 있습니다.다음과 같은 실행 가능한 메소드 생성합니다.

Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {

        }
    };

그리고 이 두 가지 방법으로 그것을 부릅니다.

new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis  // to work on mainThread

OR

new Thread(runnable).start();//to work in Background 

저는 이 전형적인 경우, 즉 일정한 간격으로 무언가를 운영하는 것을 믿습니다.Timer그게 더 적절합니다.다음은 간단한 예입니다.

myTimer = new Timer();
myTimer.schedule(new TimerTask() {          
@Override
public void run() {
    // If you want to modify a view in your Activity
    MyActivity.this.runOnUiThread(new Runnable()
        public void run(){
            tv.append("Hello World");
        });
    }
}, 1000, 1000); // initial delay 1 second, interval 1 second

사용.Timer이점은 거의 없습니다.

  • 초기 지연 및 간격은 에서 쉽게 지정할 수 있습니다.schedule함수 인수
  • 호출만 하면 타이머를 중지할 수 있습니다.myTimer.cancel()
  • 스레드를 하나만 실행하려면 호출해야 합니다.myTimer.cancel() 것을 예약하기 전에(내 타이머가 null이 아닌 경우)
Handler handler=new Handler();
Runnable r = new Runnable(){
    public void run() {
        tv.append("Hello World");                       
        handler.postDelayed(r, 1000);
    }
}; 
handler.post(r);

코틀린

private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
    val handler = Handler()
    runnable = Runnable {
        // do your work
        handler.postDelayed(runnable, 2000)
    }
    handler.postDelayed(runnable, 2000)
}

자바

Runnable runnable;
Handler handler;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            // do your work
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(runnable, 1000);
}

Handler.post 의 문서를 올바르게 이해한 경우:

Runnabler를 메시지 큐에 추가합니다.실행 테이블은 이 핸들러가 연결된 스레드에서 실행됩니다.

따라서 @alex2k8에서 제공하는 예제는 올바르게 작동하더라도 동일하지 않습니다. 여기서 우경, 어서디Handler.post()사용되며 새 스레드가 생성되지 않습니다.게시만 하면 됩니다.Runnable에 정통으로HandlerEDT에 의해 실행됩니다. 그 후 EDT는 오직 실행됩니다.Runnable.run()은 없습니다다른 것은 없어요.

기억:Runnable != Thread.

코틀린과 코루틴

코틀린에서는 코루틴을 사용하여 다음을 수행할 수 있습니다.

CoroutineScope(Dispatchers.Main).launch { // Main, because UI is changed
    ticker(delayMillis = 1000, initialDelayMillis = 1000).consumeEach {
        tv.append("Hello World")
    }
}

여기서 해보세요!

흥미로운 예는 카운터/스톱 워치가 별도의 스레드에서 실행되는 것을 지속적으로 볼 수 있다는 것입니다.GPS 위치도 표시합니다.주 활동인 사용자 인터페이스 스레드가 이미 있는 동안.

발췌:

try {    
    cnt++; scnt++;
    now=System.currentTimeMillis();
    r=rand.nextInt(6); r++;    
    loc=lm.getLastKnownLocation(best);    

    if(loc!=null) { 
        lat=loc.getLatitude();
        lng=loc.getLongitude(); 
    }    

    Thread.sleep(100); 
    handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {   
    Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}

코드를 보려면 여기를 참조하십시오.

주 활동의 사용자 인터페이스 스레드와 함께 실행 가능한 GPS 위치 및 현재 시간을 표시하는 스레드 예제

이제 Kotlin에서는 다음과 같은 방식으로 스레드를 실행할 수 있습니다.

class SimpleRunnable: Runnable {
    public override fun run() {
        println("${Thread.currentThread()} has run.")
    }
}
fun main(args: Array<String>) {
    val thread = SimpleThread()
    thread.start() // Will output: Thread[Thread-0,5,main] has run.
    val runnable = SimpleRunnable()
    val thread1 = Thread(runnable)
    thread1.start() // Will output: Thread[Thread-1,5,main] has run
}

언급URL : https://stackoverflow.com/questions/1921514/how-to-run-a-runnable-thread-in-android-at-defined-intervals

반응형