在NetworkListener回调中调用TextView的setText方法导致应用崩溃
在NetworkListener回调中调用TextView的setText方法导致应用崩溃
哥们,你这个问题我之前踩过坑!十有八九是线程不匹配搞出来的崩溃。
Android有个硬性规则:所有和UI相关的操作(比如给TextView设置文字的setText()),必须在**主线程(UI线程)**里执行。而你的NetworkListener回调方法,大概率是在子线程里被触发的——毕竟网络相关的操作一般都会放在子线程跑,避免卡主线程。这时候你直接在回调里调用view.setText("disconnected"),就相当于在子线程碰UI控件,系统直接就给你崩了。
给你几个实用的解决办法,挑适合你的来:
用Activity的
runOnUiThread(最简单)
如果你的代码是在Activity里写的,直接把UI操作包进这个方法里,它会帮你切换到主线程执行:runOnUiThread(new Runnable() { @Override public void run() { view.setText("disconnected"); } });用主线程Handler
要是你在Fragment或者其他类里,没法直接用runOnUiThread,可以创建一个绑定主线程Looper的Handler,把UI操作post进去:Handler mainHandler = new Handler(Looper.getMainLooper()); mainHandler.post(new Runnable() { @Override public void run() { view.setText("disconnected"); } });用LiveData(推荐,适合Jetpack项目)
如果你用了Jetpack组件,把网络状态放到LiveData里,让Activity/Fragment去观察它——LiveData会自动在主线程回调更新UI,根本不用自己管线程切换:// 先定义一个LiveData对象 MutableLiveData<String> networkStatus = new MutableLiveData<>(); // 在NetworkListener回调里更新LiveData(postValue可以在子线程调用) networkStatus.postValue("disconnected"); // 在Activity里观察LiveData,更新UI networkStatus.observe(this, status -> { view.setText(status); });
另外你可以去看一下崩溃日志,应该会有类似Only the original thread that created a view hierarchy can touch its views的报错,这就完全实锤是线程问题了。
备注:内容来源于stack exchange,提问作者MineRickStar
相关产品推荐
相关产品推荐

