ary*_*axt 716 java android delay handler
我希望能够在指定的延迟后调用以下方法.在目标c中有类似的东西:
[self performSelector:@selector(DoSomething) withObject:nil afterDelay:5];
Run Code Online (Sandbox Code Playgroud)
android中有没有与java相同的方法?例如,我需要能够在5秒后调用方法.
public void DoSomething()
{
//do something here
}
Run Code Online (Sandbox Code Playgroud)
kon*_*ity 1746
Handler().postDelayed({
//Do something after 100ms
}, 100)
Run Code Online (Sandbox Code Playgroud)
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
Run Code Online (Sandbox Code Playgroud)
Jul*_*lle 310
在我的案例中,我无法使用任何其他答案.我使用了原生的Java Timer.
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// this code will be executed after 2 seconds
}
}, 2000);
Run Code Online (Sandbox Code Playgroud)
eri*_*son 182
注意:当问题没有将Android指定为上下文时,会给出此答案.有关Android UI线程的具体答案请查看此处.
看起来Mac OS API允许当前线程继续,并安排任务以异步方式运行.在Java中,java.util.concurrent包提供了等效功能.我不确定Android可能会施加什么限制.
private static final ScheduledExecutorService worker =
Executors.newSingleThreadScheduledExecutor();
void someMethod() {
?
Runnable task = new Runnable() {
public void run() {
/* Do something… */
}
};
worker.schedule(task, 5, TimeUnit.SECONDS);
?
}
Run Code Online (Sandbox Code Playgroud)
pom*_*ber 101
用于在5秒后在UI线程中执行某些操作:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
//Do something here
}
}, 5000);
Run Code Online (Sandbox Code Playgroud)
Hos*_*eeb 38
你可以在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);
}
});
Run Code Online (Sandbox Code Playgroud)
ary*_*axt 36
感谢所有出色的答案,我找到了最适合我需求的解决方案.
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
}
}
Run Code Online (Sandbox Code Playgroud)
Osc*_*Ryz 20
看这个演示:
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?");
}
}
Run Code Online (Sandbox Code Playgroud)
noo*_*oob 20
如果必须使用Handler,但是您进入另一个线程,则可以使用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);
}
});
Run Code Online (Sandbox Code Playgroud)
看起来很乱,但这是其中一种方式.
cod*_*zjx 16
我更喜欢使用View.postDelayed()方法,简单的代码如下:
mView.postDelayed(new Runnable() {
@Override
public void run() {
// Do something after 1000 ms
}
}, 1000);
Run Code Online (Sandbox Code Playgroud)
Khe*_*raj 15
Kotlin和Java很多方法
HandlerHandler().postDelayed({
TODO("Do something")
}, 2000)
Run Code Online (Sandbox Code Playgroud)
Timer().schedule(object : TimerTask() {
override fun run() {
TODO("Do something")
}
}, 2000)
Run Code Online (Sandbox Code Playgroud)
甚至更短
Timer().schedule(timerTask {
TODO("Do something")
}, 2000)
Run Code Online (Sandbox Code Playgroud)
或者最短的
Timer().schedule(2000) {
TODO("Do something")
}
Run Code Online (Sandbox Code Playgroud)
ExecutorsExecutors.newSingleThreadScheduledExecutor().schedule({
TODO("Do something")
}, 2, TimeUnit.SECONDS)
Run Code Online (Sandbox Code Playgroud)
在Java中
Handlernew Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something
}
}, 2000);
Run Code Online (Sandbox Code Playgroud)
Timernew Timer().schedule(new TimerTask() {
@Override
public void run() {
// Do something
}
}, 2000);
Run Code Online (Sandbox Code Playgroud)
ScheduledExecutorServiceprivate static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = new Runnable() {
public void run() {
// Do something
}
};
worker.schedule(runnable, 2, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
Ale*_*ecs 14
这是我最简短的解决方案:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
}
}, 100);
Run Code Online (Sandbox Code Playgroud)
Vis*_*hnu 10
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);
Run Code Online (Sandbox Code Playgroud)
Wil*_*ran 10
大多数答案都使用处理程序,但我给出了一个不同的解决方案来延迟活动、片段、使用 Android Lifecycle ext 的视图模型。这种方式将在生命周期开始时自动取消 -避免内存泄漏或应用程序崩溃
在活动或片段中:
lifecycleScope.launch {
delay(DELAY_MS)
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
在视图模型中:
viewModelScope.lanch {
delay(DELAY_MS)
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
在挂起函数中:(Kotlin 协程)
suspend fun doSomethingAfter(){
delay(DELAY_MS)
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
如果你得到一个错误与lifecycleScope没有发现-进口gradle这个文件:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Android Studio 3.0及更高版本,则可以使用lambda表达式.该方法callMyMethod()在2秒后调用:
new Handler().postDelayed(() -> callMyMethod(), 2000);
Run Code Online (Sandbox Code Playgroud)
如果您需要取消延迟的runnable,请使用:
Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);
// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);
Run Code Online (Sandbox Code Playgroud)
所以这里有一些事情需要考虑,因为有很多方法可以给这只猫剥皮。虽然答案都已经给出了选择和选择。我认为使用适当的编码指南重新审视这一点很重要,以避免任何人仅仅因为“大多数人选择简单答案”而走错方向。
因此,首先让我们讨论简单的延迟后答案,即本主题中的整体获胜者选择答案。
有几件事需要考虑。在后期延迟之后,您可能会遇到内存泄漏、死对象、已经消失的生命周期等等。因此,正确处理它也很重要。您可以通过多种方式执行此操作。
为了现代发展,我将在 KOTLIN 中提供
这是在回调上使用 UI 线程的一个简单示例,并在您点击回调时确认您的活动仍然有效。
Handler(Looper.getMainLooper()).postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
Run Code Online (Sandbox Code Playgroud)
然而,这仍然不完美,因为如果活动已经消失,没有理由点击您的回调。所以更好的方法是保留对它的引用并像这样删除它的回调。
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)
}
}
Run Code Online (Sandbox Code Playgroud)
并且当然处理 onPause 上的清理,因此它不会命中回调。
override fun onPause() {
super.onPause()
mHandler.removeCallbacks(null)
}
Run Code Online (Sandbox Code Playgroud)
现在我们已经讨论了显而易见的事情,让我们来谈谈现代协程和 kotlin 的更清洁的选择:)。如果你还没有使用这些,你真的错过了。
fun doActionAfterDelay()
launch(UI) {
delay(MS_TO_DELAY)
actionToTake()
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想始终在该方法上启动 UI,您可以简单地执行以下操作:
fun doActionAfterDelay() = launch(UI){
delay(MS_TO_DELAY)
actionToTake()
}
Run Code Online (Sandbox Code Playgroud)
当然,就像 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}")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
//处理清理
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
}
}
Run Code Online (Sandbox Code Playgroud)
如果您将启动(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}")
}
}
Run Code Online (Sandbox Code Playgroud)
对于 Simple line Handle Post 延迟,您可以执行以下操作:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// Do someting
}
}, 3000);
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助
小智 5
您可以使用新引入的 lambda 表达式使其更清晰:
new Handler().postDelayed(() -> {/*your code here*/}, time);
Run Code Online (Sandbox Code Playgroud)
您可以将此用于最简单的解决方案:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//Write your code here
}
}, 5000); //Timer is in ms here.
Run Code Online (Sandbox Code Playgroud)
另外,下面可以是另一个干净有用的解决方案:
new Handler().postDelayed(() ->
{/*Do something here*/},
5000); //time in ms
Run Code Online (Sandbox Code Playgroud)