CountDownTimer 导致的一个崩溃 (Can't create handler inside thread that has not called Looper.prepare())
2017-11-21 10:57
519 查看
Section1 现象
new Thread(new Runnable() { @Override public void run() { new CountDownTimer(10000, 1000) { @Override public void onTick(long l) { } @Override public void onFinish() { } }.start(); }}).start();以上代码会导致: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()====================================================Section2 原因原因:查看CountDonwTimer的源码的最后面我们可以看到: // handles counting downprivate Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {synchronized (CountDownTimer.this) {if (mCancelled) {return;}final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();if (millisLeft <= 0) {onFinish();} else if (millisLeft < mCountdownInterval) {// no tick, just delay until donesendMessageDelayed(obtainMessage(MSG), millisLeft);} else {long lastTickStart = SystemClock.elapsedRealtime();onTick(millisLeft);// take into account user's onTick taking time to executelong delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();// special case: user's onTick took more than interval to// complete, skip to next intervalwhile (delay < 0) delay += mCountdownInterval;sendMessageDelayed(obtainMessage(MSG), delay);}}}};}
也就是说CountDownTimer 内部有一个随着对象初始化的成员变量handler,所以如果在没有Looper Prepare 的线程new 一个 CountDownTimer ,自然会有上述错误。
Section3 回调线程
===================================
测试回调线程
new CountDownTimer(5000, 1000) { @Override public void onTick(long l) { Log.i("MainActivity","l==>"+l+"ThreadName==>"+Thread.currentThread().getName()); } @Override public void onFinish() { Log.i("MainActivity","finish==>"+"ThreadName==>"+Thread.currentThread().getName()); } }.start();
打印结果如下:
12-14 10:52:34.504 3824-3824/com.example.administrator.myapplication I/MainActivity: l==>4935ThreadName==>main 12-14 10:52:35.504 3824-3824/com.example.administrator.myapplication I/MainActivity: l==>3935ThreadName==>main 12-14 10:52:36.505 3824-3824/com.example.administrator.myapplication I/MainActivity: l==>2933ThreadName==>main 12-14 10:52:37.506 3824-3824/com.example.administrator.myapplication I/MainActivity: l==>1932ThreadName==>main 12-14 10:52:39.439 3824-3824/com.example.administrator.myapplication I/MainActivity: finish==>ThreadName==>main
结论
==================================================================================
我们做出如下结论:
1.CountDownTimer 内部有new Handler 的逻辑,所以需要在主线程或者在Looper prepare 之后的线程中调用
2.CountDownTimer 的回调最终也是在其调用线程。后记这个破bug,耽误了我好几个小时,updateExperimentResult() 这个方法回调会在子线程,而我在回调里面开了timer,但是开timer这个地方又有别的地方会调用。。
所以我一直以为是别地地方的问题。。。
改别人的代码,真是坑。。。。。。这种问题,单看的时候比较简单,但是当和各种其他问题交杂在一块的时候,就不是那么容易发现的了
相关文章推荐
- Android在Activity中启动一个新进程报错:Can't create handler inside thread that has not called Looper.prepare()。
- 记录一次因为Android版本不同导致的crash异常:Can't create handler inside thread that has not called Looper.prepare()
- Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare()
- Can't create handler inside thread that has not called Looper.prepare()
- 错误: Can't create handler inside thread that has not called Looper.prepare()
- java.lang.RuntimeException:Can‘t create handler inside thread that has not called Looper.prepare()
- 错误解决 Can't create handler inside thread that has not called Looper.prepare()
- Can't create handler inside thread that has not called Looper.prepare()
- 解决bug:运行项目时报异常 “Can't create handler inside thread that has not called Looper.prepare()”
- 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()
- Android蓝牙开发,报BluetoothAdapter﹕ Can't create handler inside thread that has not called Looper.prepare
- Can't create handler inside thread that has not called Looper.prepare()
- Can’t create handler inside thread that has not called Looper.prepare()
- 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()
- Can't create handler inside thread that has not called Looper.prepare()
- Can't create handler inside thread that has not called Looper.prepare() 错误
- can't create handler inside thread that has not called Looper.prepare
- Android : Can't create handler inside thread that has not called Looper.prepare()
- 异常:Can't create handler inside thread that has not called Looper.prepare()解决办法
- Can't create handler inside thread that has not called Looper.prepare()