java - 当我第一次运行我的应用程序时,你不认为 runTimer() 方法会无限运行,因此永远不会调用 onStart() 方法吗?
问题描述
我的 OnStart() 方法不应被调用,因为我的 onCreate() 方法将无限运行。当 OnCreate 方法运行时,会调用 runTimer() 方法。这个runTimer方法会因为handler.postDelayed而无限运行。Android Studio 是如何完成 runTimer() 方法的无限循环然后调用 OnStart() 方法的?
// MY STOPWATCH APP
public class MainActivity extends AppCompatActivity {
private int seconds = 0;
private boolean running;
private boolean wasRunning;
@Override
// ON RUNNING MY APP FOR THE FIRST TIME THIS METHOD WILL GET CALLED FIRST.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
seconds = savedInstanceState.getInt("seconds");
running = savedInstanceState.getBoolean("running");
wasRunning = savedInstanceState.getBoolean("wasRunning");
}
runTimer();
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("seconds", seconds);
savedInstanceState.putBoolean("running", running);
savedInstanceState.putBoolean("wasRunning", wasRunning);
}
@Override
protected void onStop() {
super.onStop();
wasRunning = running;
running = false;
}
@Override
protected void onStart() {
super.onStart();
if (wasRunning) {
running = true;
}
}
//Start the stopwatch running when the Start button is clicked.
public void onClickStart(View view) {
running = true;
}
//Stop the stopwatch running when the Stop button is clicked.
public void onClickStop(View view) {
running = false;
}
//Reset the stopwatch when the Reset button is clicked.
public void onClickReset(View view) {
running = false;
seconds = 0;
}
//Sets the number of seconds on the timer.
private void runTimer() {
final TextView timeView = (TextView)findViewById(R.id.tv_time_view);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
int hours = seconds/3600;
int minutes = (seconds%3600)/60;
int secs = seconds%60;
String time = String.format(Locale.getDefault(),
"%d:%02d:%02d", hours, minutes, secs);
timeView.setText(time);
if (running) {
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
}
解决方案
为什么你认为它runTimer()
会无限期地运行?
handler.post()
并将handler.postDelayed()
对象(您的new Runnable() {}
)添加到消息队列中,以便run()
稍后可以执行对象方法。
handler.post()
在将对象添加到消息队列后返回,因此runTimer()
andonCreate()
方法正常完成。
为什么是“消息队列”?因为文档是这样说的:
https://developer.android.com/reference/android/os/Handler:
处理程序允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象
https://developer.android.com/reference/android/os/Handler#post(java.lang.Runnable):
使 Runnable r 添加到消息队列中。可运行对象将在附加此处理程序的线程上运行。
https://developer.android.com/reference/android/os/Handler#postDelayed(java.lang.Runnable,%20long):
使 Runnable r 添加到消息队列中,在经过指定的时间后运行。
使用 a 的全部意义Handler
在于允许Runnable
被编辑的 spost()
在稍后的某个时间点执行,以便当前线程可以继续其工作。
如果处理程序将在直接(和阻塞)内执行代码,Runnable
那么您可以将代码编写为new Runnable() { /*...*/ }.run();
推荐阅读
- node.js - Heroku 上的粘性会话
- javascript - net::ERR_CERT_COMMON_NAME_INVALID 使用 fetch API 向 metaweather API 发出请求时出错
- swift - 如何在所有 iPhone 设备和模拟器中将 UIView 定位在 UIImage 之上
- sql - 用 DB2 / SQL 中的另一个大表过滤一个大表的最佳方法?
- r - 如何在 R 中使用具有多个条件的排名函数 Row_number
- python - 用 Python 抓取网页,BeautifulSoup findAll() 找不到所有
- html - 尝试播放视频时,iframe 继续在另一个选项卡上打开链接
- javascript - 如何修复节点 js 中的设置标头?
- sql - 如果任何值为空,我将如何在选择上返回一个空字符串?
- amazon-web-services - Amazon Cognito 注销终端节点未按预期工作