有一段代码我使用postDelayed和主线程上执行的其他一些代码。我跑了几次,总是看到以下输出:
07-13 14:22:18.511 15376-15376 / sample1.com.sample_1 D / MainActivity:i = 0
...
07-13 14:22:18.601 15376-15376 / sample1.com.sample_1 D / MainActivity: onResume 07-13 14:22:18.601 15376-15376 / sample1.com.sample_1 D / MainActivity:postDelayed
从日志输出中可以看出,延迟时间为50毫秒并不重要。消息" postDelayed"在大约100毫秒(601-511 = 90)之后键入。看起来延迟的runnable被添加到我的UI线程的消息队列的末尾。但无论如何,是否有关于何时输入postDelayed的保证?它可以在for循环的中间输入吗?
package sample1.com.sample_1;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d("MainActivity", "postDelayed");
}
}, 10);
for (int i = 0; i < 10000; i++) {
Log.d("MainActivity", "i = " + i);
}
}
@Override
protected void onResume() {
Log.d("MainActivity", "onResume");
super.onResume();
}
}
答案 0 :(得分:2)
还有来自其他服务和应用程序的日志,因此根据日志输出计算Handler延迟将不正确。 Android上的日志记录机制有自己的队列,因此您的消息实际上可能因队列中的其他日志而延迟。
我的建议是使用System.nanoTime()来计算处理程序延迟之间的时间。据我所知,它提供了最精确的计时器值。
最后要回答你的问题,不能指出行动发生的确切时间。有数千个(如果不是数百万个)不同的条件可能会延迟应用程序的操作,特别是如果它是异步操作。
编辑:这种延迟不能保证恰好50ms延迟,但它可以保证至少&#34;至少&#34; 50ms延迟。
答案 1 :(得分:1)
跟踪Handler.postDelay()
的代码后,看起来最终会调用MessageQueue.enqueueMessage()
。从代码中,它似乎无限循环遍历消息队列,直到它到达结束或直到当前任务时间高于我们的延迟时间,然后将任务插入到队列中的该位置。这意味着执行任务之前的队列花费的时间非常长,您应该在几毫秒内执行任务。
我猜你的操作不是问题,而是Android忙于主线程渲染你的UI和其他内部工作,这就是推迟你的任务。据推测,执行活动中onCreate
,onStart
,onResume
的所有代码及其扩展的类在postDelay时间+ 10ms之前排队。
100ms大约是6帧,所以它可能只是显示你的活动的UI所花费的时间,尝试在按钮点击上执行你的postDelay,我相信时间会更加可预测,因为UI和Activity不是正在安装或拆除。
答案 2 :(得分:0)
使用post()
实际调用sendMessageDelayed(getPostMessage(r), 0)
,postDelayed()
将调用sendMessageDelayed(getPostMessage(r), delayMillis)
,它们类似。
post...()
方法最终将调用queue.enqueueMessage,when
param不同,它决定将msg插入消息队列的位置。你可以改变队列中的msg,但不能中断msg的运行。