답변:
Handler().postDelayed({
//Do something after 100ms
}, 100)
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
removeCallbacks(Runnable r)
온 Handler
.
import android.os.handler
내 경우에는 다른 답변을 사용할 수 없습니다. 대신 기본 Java 타이머를 사용했습니다.
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// this code will be executed after 2 seconds
}
}, 2000);
참고 : 이 답변은 질문에 Android를 컨텍스트로 지정하지 않았을 때 제공되었습니다. Android UI 스레드와 관련된 답변 은 여기를 참조하십시오.
Mac OS API가 현재 스레드를 계속 사용하고 작업이 비동기 적으로 실행되도록 예약하는 것처럼 보입니다. Java에서는 동등한 기능이 java.util.concurrent
패키지에서 제공됩니다 . 안드로이드가 어떤 제한을 부과하는지 잘 모르겠습니다.
private static final ScheduledExecutorService worker =
Executors.newSingleThreadScheduledExecutor();
void someMethod() {
⋮
Runnable task = new Runnable() {
public void run() {
/* Do something… */
}
};
worker.schedule(task, 5, TimeUnit.SECONDS);
⋮
}
ScheduledFuture<?>
반환 된에 대한 참조를 저장하고 worker.schedule()
해당 cancel(boolean)
메소드를 호출 하기 만하면 됩니다.
ScheduledExecutorService
.
5 초 후에 UI 스레드에서 무언가를 실행하는 경우 :
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
//Do something here
}
}, 5000);
UIThread 내에서 Handler를 사용할 수 있습니다.
runOnUiThread(new Runnable() {
@Override
public void run() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//add your code here
}
}, 1000);
}
});
모든 훌륭한 답변에 감사드립니다. 내 요구에 가장 적합한 솔루션을 찾았습니다.
Handler myHandler = new DoSomething();
Message m = new Message();
m.obj = c;//passing a parameter here
myHandler.sendMessageDelayed(m, 1000);
class DoSomething extends Handler {
@Override
public void handleMessage(Message msg) {
MyObject o = (MyObject) msg.obj;
//do something here
}
}
Kotlin
&Java
여러 가지 방법
Handler
Handler().postDelayed({
TODO("Do something")
}, 2000)
Timer().schedule(object : TimerTask() {
override fun run() {
TODO("Do something")
}
}, 2000)
또는 더 짧은
Timer().schedule(timerTask {
TODO("Do something")
}, 2000)
또는 가장 짧은 것은
Timer().schedule(2000) {
TODO("Do something")
}
Executors
Executors.newSingleThreadScheduledExecutor().schedule({
TODO("Do something")
}, 2, TimeUnit.SECONDS)
자바에서
Handler
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something
}
}, 2000);
Timer
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// Do something
}
}, 2000);
ScheduledExecutorService
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = new Runnable() {
public void run() {
// Do something
}
};
worker.schedule(runnable, 2, TimeUnit.SECONDS);
How to call a method after a delay in Android
입니다. 그래서 나는 그것에 주저했다. 요점. 그렇지 않으면 Java 누출은 개발자에게 별도로 이해하는 큰 주제입니다.
이 데모를보십시오 :
import java.util.Timer;
import java.util.TimerTask;
class Test {
public static void main( String [] args ) {
int delay = 5000;// in ms
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
System.out.println("Wait, what..:");
}
}, delay);
System.out.println("Would it run?");
}
}
핸들러를 사용해야하지만 다른 스레드에 runonuithread
있는 경우 UI 스레드에서 핸들러를 실행하는 데 사용할 수 있습니다 . 이렇게하면 호출 요청 예외에서 당신을 저장합니다Looper.Prepare()
runOnUiThread(new Runnable() {
@Override
public void run() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 1 second
}
}, 1000);
}
});
꽤 지저분 해 보이지만 이것은 방법 중 하나입니다.
View.postDelayed()
아래의 간단한 코드 를 사용하는 방법을 선호 합니다.
mView.postDelayed(new Runnable() {
@Override
public void run() {
// Do something after 1000 ms
}
}, 1000);
당신이 사용하는 경우 안드로이드 스튜디오 3.0 이상 당신은 람다 표현식을 사용할 수 있습니다. 이 메소드 callMyMethod()
는 2 초 후에 호출됩니다.
new Handler().postDelayed(() -> callMyMethod(), 2000);
지연된 실행 가능을 취소해야하는 경우 다음을 사용하십시오.
Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);
// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);
Timer를 제안합니다 . 매우 특정 간격으로 메소드가 호출되도록 예약 할 수 있습니다. 이렇게하면 UI가 차단되지 않으며 메서드가 실행되는 동안 앱이 공명 상태를 유지합니다.
다른 옵션은 wait ()입니다. 메서드를 사용하면 지정된 시간 동안 현재 스레드를 차단합니다. UI 스레드에서이 작업을 수행하면 UI가 응답하지 않습니다.
가장 간단한 솔루션에 사용할 수 있습니다.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Write your code here
}
}, 5000); //Timer is in ms here.
그렇지 않으면 아래에 또 다른 유용한 유용한 솔루션이 있습니다.
new Handler().postDelayed(() ->
{/*Do something here*/},
5000); //time in ms
이 고양이를 피부에 바르는 방법이 많으므로 여기에서 고려해야 할 사항이 몇 가지 있습니다. 답변이 모두 선택되어 선택되었지만. 나는 이것이 "주요 선정 된 간단한 답변"때문에 누군가가 잘못된 방향으로 나아가는 것을 피하기 위해 적절한 코딩 지침으로 다시 방문하는 것이 중요하다고 생각합니다.
먼저이 스레드에서 전체적으로 선정 된 답변 인 간단한 Post Delayed 답변에 대해 설명하겠습니다.
고려해야 할 몇 가지. 포스트 지연 후 메모리 누수, 죽은 객체, 수명주기 등이 발생할 수 있습니다. 따라서 올바르게 처리하는 것도 중요합니다. 몇 가지 방법으로이 작업을 수행 할 수 있습니다.
현대적인 발전을 위해 코 틀린에 공급하겠습니다
다음은 콜백에서 UI 스레드를 사용하고 콜백을 칠 때 액티비티가 여전히 살아 있는지 확인하는 간단한 예입니다.
Handler(Looper.getMainLooper()).postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
그러나 활동이 중단 된 경우 콜백을 칠 이유가 없으므로 여전히 완벽하지 않습니다. 더 좋은 방법은 참조를 유지하고 콜백을 제거하는 것입니다.
private fun showFacebookStylePlus1NewsFeedOnPushReceived(){
A35Log.v(TAG, "showFacebookStylePlus1NewsFeedOnPushReceived")
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.VISIBLE
mHandler.postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
}
}
물론 onPause에서 정리를 처리하여 콜백에 닿지 않도록하십시오.
override fun onPause() {
super.onPause()
mHandler.removeCallbacks(null)
}
이제 우리는 명백한 것을 이야기 했으므로 현대 코 루틴과 kotlin으로 깔끔한 옵션에 대해 이야기 해 봅시다. :). 아직 사용하지 않으면 실제로 누락 된 것입니다.
fun doActionAfterDelay()
launch(UI) {
delay(MS_TO_DELAY)
actionToTake()
}
}
또는 해당 메소드에서 항상 UI 실행을 수행하려면 다음을 수행하십시오.
fun doActionAfterDelay() = launch(UI){
delay(MS_TO_DELAY)
actionToTake()
}
물론 PostDelayed와 마찬가지로 취소 호출을 처리해야 지연 호출 후 활동 확인을 수행하거나 다른 경로와 마찬가지로 onPause에서 취소 할 수 있습니다.
var mDelayedJob: Job? = null
fun doActionAfterDelay()
mDelayedJob = launch(UI) {
try {
delay(MS_TO_DELAY)
actionToTake()
}catch(ex: JobCancellationException){
showFancyToast("Delayed Job canceled", true, FancyToast.ERROR, "Delayed Job canceled: ${ex.message}")
}
}
}
}
// 핸들 정리
override fun onPause() {
super.onPause()
if(mDelayedJob != null && mDelayedJob!!.isActive) {
A35Log.v(mClassTag, "canceling delayed job")
mDelayedJob?.cancel() //this should throw CancelationException in coroutine, you can catch and handle appropriately
}
}
launch (UI)를 메소드 서명에 넣으면 호출 코드 행에서 작업을 지정할 수 있습니다.
따라서 이야기의 도덕은 지연된 조치로 안전하고, 콜백을 제거하거나, 작업을 취소하고 지연 콜백에서 항목을 터치 할 수있는 올바른 수명주기가 있는지 확인하는 것입니다. 코 루틴은 또한 취소 가능한 작업을 제공합니다.
또한 일반적으로 코 루틴과 함께 발생할 수있는 다양한 예외를 처리해야합니다. 예를 들어, 취소, 예외, 시간 초과 등 사용하기로 결정한 모든 것. 코 루틴을 실제로 사용하기로 결정한 경우 고급 예입니다.
mLoadJob = launch(UI){
try {
//Applies timeout
withTimeout(4000) {
//Moves to background thread
withContext(DefaultDispatcher) {
mDeviceModelList.addArrayList(SSDBHelper.getAllDevices())
}
}
//Continues after async with context above
showFancyToast("Loading complete", true, FancyToast.SUCCESS)
}catch(ex: JobCancellationException){
showFancyToast("Save canceled", true, FancyToast.ERROR, "Save canceled: ${ex.message}")
}catch (ex: TimeoutCancellationException) {
showFancyToast("Timed out saving, please try again or press back", true, FancyToast.ERROR, "Timed out saving to database: ${ex.message}")
}catch(ex: Exception){
showFancyToast("Error saving to database, please try again or press back", true, FancyToast.ERROR, "Error saving to database: ${ex.message}")
}
}
이것을 호출하는 더 간단한 방법을 만들었습니다.
public static void CallWithDelay(long miliseconds, final Activity activity, final String methodName)
{
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
Method method = activity.getClass().getMethod(methodName);
method.invoke(activity);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}, miliseconds);
}
사용하려면 다음을 호출하십시오. .CallWithDelay(5000, this, "DoSomething");
performSelector
. 이것이 가장 좋은 방법입니다.
당신이 얻을 때 하나 아래 작동
java.lang.RuntimeException : Looper.prepare ()를 호출하지 않은 스레드 내에 핸들러를 작성할 수 없습니다.
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
를 사용하는 것은 매우 쉽습니다 CountDownTimer
. 자세한 내용은 https://developer.android.com/reference/android/os/CountDownTimer.html
import android.os.CountDownTimer;
// calls onTick every second, finishes after 3 seconds
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
Log.d("log", millisUntilFinished / 1000);
}
public void onFinish() {
// called after count down is finished
}
}.start();
모두 새로운 런너 블 또는 메시지를 게시하기 전에 처리기를 청소하는 것을 잊어 버린 것 같습니다. 그렇지 않으면 잠재적으로 축적되어 나쁜 행동을 일으킬 수 있습니다.
handler.removeMessages(int what);
// Remove any pending posts of messages with code 'what' that are in the message queue.
handler.removeCallbacks(Runnable r)
// Remove any pending posts of Runnable r that are in the message queue.
또 다른 까다로운 방법은 다음과 같습니다. 실행 가능한 UI 요소 변경시 예외가 발생하지 않습니다.
public class SimpleDelayAnimation extends Animation implements Animation.AnimationListener {
Runnable callBack;
public SimpleDelayAnimation(Runnable runnable, int delayTimeMilli) {
setDuration(delayTimeMilli);
callBack = runnable;
setAnimationListener(this);
}
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
callBack.run();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
다음과 같이 애니메이션을 호출 할 수 있습니다.
view.startAnimation(new SimpleDelayAnimation(delayRunnable, 500));
애니메이션은 모든 뷰에 첨부 할 수 있습니다.
안드로이드에서 적합한 솔루션 :
private static long SLEEP_TIME = 2 // for 2 second
.
.
MyLauncher launcher = new MyLauncher();
launcher.start();
.
.
private class MyLauncher extends Thread {
@Override
/**
* Sleep for 2 seconds as you can also change SLEEP_TIME 2 to any.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME * 1000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
//do something you want to do
//And your code will be executed after 2 second
}
}
비슷한 솔루션이지만 사용하기에 훨씬 더 깨끗합니다.
이 함수를 클래스 외부에 작성하십시오
fun delay(duration: Long, `do`: () -> Unit) {
Handler().postDelayed(`do`, duration)
}
용법:
delay(5000) {
//Do your work here
}
do
내장 된 메소드이므로 변수 이름으로 사용하려면`를 사용해야합니다
do
3 초의 지연 후 이렇게 생각했다
안드로이드에서는 모든 함수의 지연 실행을 위해 kotlin 코드 아래에 작성할 수 있습니다
class MainActivity : AppCompatActivity() {
private lateinit var handler: Handler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handler= Handler()
handler.postDelayed({
doSomething()
},2000)
}
private fun doSomething() {
Toast.makeText(this,"Hi! I am Toast Message",Toast.LENGTH_SHORT).show()
}
}