Android에서 지연된 후 메소드를 호출하는 방법
나는 지정된 지연 후에 다음 방법으로 전화할 수 있기를 원한다.객관적인 c에서는 다음과 같은 것이 있었다.
[self performSelector:@selector(DoSomething) withObject:nil afterDelay:5];
자바를 가진 안드로이드에 이 방법과 동등한 것이 있는가?예를 들어 나는 5초 후에 메소드를 호출할 수 있어야 해.
public void DoSomething()
{
//do something here
}
코틀린
Handler(Looper.getMainLooper()).postDelayed({
//Do something after 100ms
}, 100)
자바
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
나는 내 경우에 다른 어떤 대답도 사용할 수 없었다.나는 대신 네이티브 자바 타이머를 사용했다.
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.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);
⋮
}
5초 후에 UI 스레드에서 무언가를 실행하는 경우:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
//Do something here
}
}, 5000);
Kotlin
&Java
여러 가지 방법
1. 사용Handler
Handler().postDelayed({
TODO("Do something")
}, 2000)
2. TimerTask 사용
Timer().schedule(object : TimerTask() {
override fun run() {
TODO("Do something")
}
}, 2000)
아니면 심지어 더 짧다.
Timer().schedule(timerTask {
TODO("Do something")
}, 2000)
아니면 가장 짧을 것이다.
Timer().schedule(2000) {
TODO("Do something")
}
. 3.. 사용Executors
Executors.newSingleThreadScheduledExecutor().schedule({
TODO("Do something")
}, 2, TimeUnit.SECONDS)
자바에서
1. 사용Handler
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something
}
}, 2000);
2. 사용Timer
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// Do something
}
}, 2000);
. 3.. 사용ScheduledExecutorService
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = new Runnable() {
public void run() {
// Do something
}
};
worker.schedule(runnable, 2, TimeUnit.SECONDS);
UIThread 내의 처리기를 사용할 수 있음:
runOnUiThread(new Runnable() {
@Override
public void run() {
new 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
}
}
다음 데모를 참조하십시오.
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);
가장 짧은 해결책은 다음과 같다.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
Android Studio 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);
안전 강화 - Kotlin Coroutine 사용
대부분의 답변은 Handroid Lifecycle을 사용하지만 나는 Android Lifecycle extend로 활동, 단편, 보기 모델 지연을 위한 다른 솔루션을 제공한다.이렇게 하면 라이프사이클이 파괴되기 시작할 때 자동으로 취소됨 - 메모리 누수 또는 앱 충돌 방지
활동 또는 조각에서:
lifecycleScope.launch {
delay(DELAY_MS)
doSomething()
}
ViewModel에서:
viewModelScope.lanch {
delay(DELAY_MS)
doSomething()
}
일시 중단 함수: (Kotlin Coroutine)
suspend fun doSomethingAfter(){
delay(DELAY_MS)
doSomething()
}
라이프사이클에 오류가 발생하는 경우스코프를 찾을 수 없음! - 이 종속성을 앱 그라들 파일로 가져오기:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
//DO SOME ACTIONS HERE , THIS ACTIONS WILL WILL EXECUTE AFTER 5 SECONDS...
}
});
}
}, 5000);
타이머를 추천한다. 타이머를 사용하면 아주 특정한 간격으로 호출할 수 있는 방법을 계획할 수 있다.이렇게 하면 UI가 차단되지 않으며 메서드가 실행되는 동안 앱의 재전송 상태를 유지할 수 있다.
다른 옵션은 wait(); 메서드인데, 이렇게 하면 지정된 시간 동안 현재 스레드가 차단된다.이렇게 하면 UI 스레드에서 UI 응답이 중지된다.
그래서 이 고양이 가죽을 벗기는 방법은 매우 많기 때문에 여기서 고려해야 할 몇 가지가 있다.이미 모든 답변이 선택과 선택으로 주어졌지만.단지 "주요 선택 단순 답변" 때문에 잘못된 방향으로 가는 사람을 피하기 위해 적절한 코딩 가이드라인을 통해 이 문제를 재검토하는 것이 중요하다고 생각한다.
먼저 이 실에서 전반적으로 선택된 정답인 간단한 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)
}
이제 뻔한 것을 다뤘으니, 현대식 코루틴과 코틀린 :)과 함께 더 깨끗한 옵션에 대해 이야기해 보자.만약 네가 아직 이것을 사용하지 않는다면, 너는 정말 놓치고 있는 거야.
fun doActionAfterDelay()
launch(UI) {
delay(MS_TO_DELAY)
actionToTake()
}
}
또는 해당 방법으로 UI를 항상 실행하려면 다음을 수행하십시오.
fun doActionAfterDelay() = launch(UI){
delay(MS_TO_DELAY)
actionToTake()
}
물론 PostDelayed와 마찬가지로 당신은 당신이 취소 처리를 확실히 해야 당신이 지연 통화 후에 활동 점검을 할 수 있거나 다른 경로와 마찬가지로 일시 정지 상태에서 그것을 취소할 수 있다.
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
}
}
실행(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}")
}
}
단순 줄 핸들 포스트 지연의 경우 다음과 같이 할 수 있다.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// Do someting
}
}, 3000);
이게 도움이 됐으면 좋겠는데
가장 간단한 솔루션에 사용할 수 있는 기능:
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
새로 도입된 람다 식을 사용하면 훨씬 깨끗하게 만들 수 있다.
new Handler().postDelayed(() -> {/*your code here*/}, time);
코틀린을 이용하여 우리는 다음과 같은 일을 함으로써 성취할 수 있다.
Handler().postDelayed({
// do something after 1000ms
}, 1000)
RxAndroid를 사용하면 스레드와 오류 처리가 훨씬 쉬워진다.지연 후 다음 코드가 실행됨
Observable.timer(delay, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> {
// Execute code here
}, Throwable::printStackTrace);
나는 이것을 부르는 더 간단한 방법을 만들었다.
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");
아래는 당신이 받을 때,
자바.의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();
나는 더 깨끗한 것을 좋아한다.다음은 메소드 내에서 사용할 인라인 코드 구현
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
모든 사람이 새로운 실행 가능 또는 메시지를 게시하기 전에 핸들러를 청소하는 것을 잊은 것 같다.그렇지 않으면 그들은 잠재적으로 축적되어 나쁜 행동을 일으킬 수 있다.
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));
애니메이션은 어떤 시각에도 붙일 수 있다.
게으르고 게으른 사람들아, 코틀린에 답이 있다.
Handler().postDelayed({
//doSomethingHere()
}, 1000)
안드로이드의 적합한 솔루션:
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
}
참조URL: https://stackoverflow.com/questions/3072173/how-to-call-a-method-after-a-delay-in-android
'IT이야기' 카테고리의 다른 글
실시간 메시징 앱에서 상태 처리 (0) | 2022.04.28 |
---|---|
GCC 기본 포함 디렉터리란? (0) | 2022.04.28 |
HMAC-SHA1에 대한 목표-C 샘플 코드 (0) | 2022.04.28 |
Vuejs 2가 어레이에서 이동하는 항목, 어레이 인덱싱 유지 안 함 (0) | 2022.04.28 |
fflush(stdin) 사용 (0) | 2022.04.28 |