source

Android에서 스레드 또는 프로세스를 일시 중지/슬립하는 방법은 무엇입니까?

manysource 2023. 8. 28. 21:13

Android에서 스레드 또는 프로세스를 일시 중지/슬립하는 방법은 무엇입니까?

두 줄의 코드 사이를 잠시 멈추고자 합니다. 조금 설명하겠습니다.

-> 사용자가 버튼(사실 카드)을 클릭하면 이 버튼의 배경을 변경하여 표시합니다.

thisbutton.setBackgroundResource(R.drawable.icon);

-> 1초 후에 배경을 변경하여 버튼의 이전 상태로 돌아가야 합니다.

thisbutton.setBackgroundResource(R.drawable.defaultcard);

-> 이 두 줄의 코드 사이에서 스레드를 일시 중지하려고 했습니다.

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

그러나 이것은 작동하지 않습니다.일시 중지해야 하는 것은 스레드가 아니라 프로세스일 수 있습니다.

저도 시도해봤지만 소용이 없었습니다.

new Reminder(5);

사용:

public class Reminder {

Timer timer;

        public Reminder(int seconds) {
            timer = new Timer();
            timer.schedule(new RemindTask(), seconds*1000);
        }

        class RemindTask extends TimerTask {
            public void run() {
                System.out.format("Time's up!%n");
                timer.cancel(); //Terminate the timer thread
            }
        }  
    }

스레드 또는 프로세스를 일시 중지/절전하려면 어떻게 해야 합니까?

문제에 대한 한 가지 해결책은 Handler.postDelayed() 메서드를 사용하는 것입니다.일부 Google 교육 자료에서는 동일한 솔루션을 제안합니다.

@Override
public void onClick(View v) {
    my_button.setBackgroundResource(R.drawable.icon);

    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() {
         @Override 
         public void run() { 
              my_button.setBackgroundResource(R.drawable.defaultcard); 
         } 
    }, 2000); 
}

그러나 일부에서는 위 솔루션이 외부 클래스인 활동에 대한 참조를 암시적으로 보유하는 정적이지 않은 내부 및 익명 클래스를 사용하기 때문에 메모리 누수를 유발한다고 지적했습니다.활동 컨텍스트가 가비지 수집된 경우 이 문제가 발생합니다.

메모리 누수를 방지하는 더 복잡한 솔루션은 다음과 같이 분류됩니다.Handler그리고.Runnable정적 내부 클래스는 외부 클래스에 대한 암묵적인 참조를 보유하지 않으므로 활동 내부에 정적 내부 클래스가 있는 경우:

private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();

public static class MyRunnable implements Runnable {
    private final WeakReference<Activity> mActivity;

    public MyRunnable(Activity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
    public void run() {
        Activity activity = mActivity.get();
        if (activity != null) {
            Button btn = (Button) activity.findViewById(R.id.button);
            btn.setBackgroundResource(R.drawable.defaultcard);
        }
    }
}

private MyRunnable mRunnable = new MyRunnable(this);

public void onClick(View view) {
    my_button.setBackgroundResource(R.drawable.icon);

    // Execute the Runnable in 2 seconds
    mHandler.postDelayed(mRunnable, 2000);
}

참고:Runnable에서는 UI에 액세스해야 하는 정적 클래스에 필요한 활동에 대한 약한 참조를 사용합니다.

당신은 이것을 시도할 수 있습니다 그것은 짧습니다.

SystemClock.sleep(7000);

경고: UI 스레드에서 이 작업을 수행하지 마십시오.

이것을 사용하여 예를 들어 배경 스레드를 절전 모드로 사용합니다.


문제의 완전한 해결책은 다음과 같습니다.사용 가능한 API 1

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View button) {
                button.setBackgroundResource(R.drawable.avatar_dead);
                final long changeTime = 1000L;
                button.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        button.setBackgroundResource(R.drawable.avatar_small);
                    }
                }, changeTime);
            }
        });

tmp 처리기를 만들지 않고도.또한 이 솔루션은 Handler에 의한 뷰를 유지하지 않기 때문에 @tronman보다 더 좋습니다.또한 불량 스레드에서 생성된 핸들러에는 문제가 없습니다;)

문서화

공공 정적 빈 공간 절전(longms)

API 레벨 1에 추가됨

복귀하기 전에 지정된 밀리초(업타임 Millis)를 기다립니다.슬립(긴 길이)과 비슷하지만 인터럽트를 던지지 않습니다.예외; 인터럽트() 이벤트는 다음 인터럽트 가능 작업까지 지연됩니다.지정한 시간(밀리초) 이상 경과할 때까지 반환되지 않습니다.

매개변수

복귀하기 전에 절전 모드로 전환(밀리초)합니다.

보기 클래스에서 지연된 postDelayed에 대한 코드:

/**
 * <p>Causes the Runnable to be added to the message queue, to be run
 * after the specified amount of time elapses.
 * The runnable will be run on the user interface thread.</p>
 *
 * @param action The Runnable that will be executed.
 * @param delayMillis The delay (in milliseconds) until the Runnable
 *        will be executed.
 *
 * @return true if the Runnable was successfully placed in to the
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.  Note that a
 *         result of true does not mean the Runnable will be processed --
 *         if the looper is quit before the delivery time of the message
 *         occurs then the message will be dropped.
 *
 * @see #post
 * @see #removeCallbacks
 */
public boolean postDelayed(Runnable action, long delayMillis) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.postDelayed(action, delayMillis);
    }
    // Assume that post will succeed later
    ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
    return true;
}

사용자:

Thread closeActivity = new Thread(new Runnable() {
  @Override
  public void run() {
    try {
      Thread.sleep(3000);
      // Do some stuff
    } catch (Exception e) {
      e.getLocalizedMessage();
    }
  }
});

CountDownTime 사용

new CountDownTimer(5000, 1000) {

    @Override
    public void onTick(long millisUntilFinished) {
        // do something after 1s
    }

    @Override
    public void onFinish() {
        // do something end times 5s
    }

}.start(); 

아마 그런 식으로 하고 싶지 않을 겁니다.명시적으로 입력함으로써sleep()버튼 클릭 이벤트 핸들러에서는 전체 UI를 1초 동안 잠글 수 있습니다.한 가지 대안은 일종의 싱글샷 타이머를 사용하는 것입니다.타이머 작업을 만들어 배경색을 다시 기본 색으로 변경하고 타이머에 예약합니다.

처리기를 사용할 수도 있습니다.타이머 사용에서 핸들러 사용으로 전환한 사람에 대한 튜토리얼이 있습니다.

참고로 프로세스를 일시 중지할 수 없습니다.Java(또는 Android) 프로세스에는 하나 이상의 스레드가 있으며 사용자는 스레드만 절전할 수 있습니다.

이것이 제가 하루의 마지막에 한 일입니다. 지금은 잘 작동합니다.

@Override
    public void onClick(View v) {
        my_button.setBackgroundResource(R.drawable.icon);
        // SLEEP 2 SECONDS HERE ...
        final Handler handler = new Handler(); 
        Timer t = new Timer(); 
        t.schedule(new TimerTask() { 
                public void run() { 
                        handler.post(new Runnable() { 
                                public void run() { 
                                 my_button.setBackgroundResource(R.drawable.defaultcard); 
                                } 
                        }); 
                } 
        }, 2000); 
    }

얀코프스키 씨의 답변 외에도, 당신은 또한 다음과 같은 것을 사용할 수 있습니다.postDelayed()이 기능은 다음 사이트에서 사용할 수 있습니다.View(를 찍고 (: 당의카드)를 찍습니다Runnable지연 기간도 있습니다.을 합니다.Runnable그 지체 후에

이것이 제 예입니다.

Java Utils 만들기

    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.Intent;

    public class Utils {

        public static void showDummyWaitingDialog(final Context context, final Intent startingIntent) {
            // ...
            final ProgressDialog progressDialog = ProgressDialog.show(context, "Please wait...", "Loading data ...", true);

            new Thread() {
                public void run() {
                    try{
                        // Do some work here
                        sleep(5000);
                    } catch (Exception e) {
                    }
                    // start next intent
                    new Thread() {
                        public void run() {
                        // Dismiss the Dialog 
                        progressDialog.dismiss();
                        // start selected activity
                        if ( startingIntent != null) context.startActivity(startingIntent);
                        }
                    }.start();
                }
            }.start();  

        }

    }    

또는 다음을 사용할 수 있습니다.

android.os.SystemClock.sleep(checkEvery)

없는 .try ... catch.

코틀린과 코루틴을 사용하면 간단히 할 수 있습니다.

GlobalScope.launch {
   delay(3000) // In ms
   //Code after sleep
}

UI를 업데이트해야 하는 경우

GlobalScope.launch {
  delay(3000)
  GlobalScope.launch(Dispatchers.Main) {
    //Action on UI thread
  }
}

오래된 스레드인 것은 알지만 Android 설명서에서 저에게 매우 적합한 솔루션을 찾았습니다.

new CountDownTimer(30000, 1000) {

    public void onTick(long millisUntilFinished) {
        mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
    }

    public void onFinish() {
        mTextField.setText("done!");
    }
}.start();

https://developer.android.com/reference/android/os/CountDownTimer.html

이게 누군가에게 도움이 되길...

  class MyActivity{
    private final Handler handler = new Handler();
    private Runnable yourRunnable;
    protected void onCreate(@Nullable Bundle savedInstanceState) {
       // ....
       this.yourRunnable = new Runnable() {
               @Override
               public void run() {
                   //code
               }
            };

        this.handler.postDelayed(this.yourRunnable, 2000);
       }


     @Override
  protected void onDestroy() {
      // to avoid memory leaks
      this.handler.removeCallbacks(this.yourRunnable);
      }
    }

그리고 트론맨 답변에 설명된 대로 "정적 클래스" 방법과 결합할 수 있다는 것을 두 번 확인합니다.

언급URL : https://stackoverflow.com/questions/1520887/how-to-pause-sleep-thread-or-process-in-android