在Fragment中设置文本颜色,退出时触发空指针崩溃该如何解决?
问题成因
崩溃的核心原因是异步任务生命周期与Fragment生命周期不一致:
- 你实现的
TickData是后台运行的定时任务,每隔1秒就会向主线程Handler发送UI更新任务 - 当你退出Fragment时,Fragment已经和宿主Activity完成解绑,此时
getActivity()会返回null - 还在队列中待执行的UI更新任务触发时,调用
getResources()本质是调用宿主Activity的方法,此时Activity引用为空,就触发了空指针异常。缓慢退出的场景刚好卡在Fragment解绑、UI任务刚好执行的时间点,所以容易复现崩溃。
修复方案
可以从「执行UI操作前校验状态」和「销毁时主动清理任务」两个维度修复:
UI更新前先校验Fragment状态,避免访问已经销毁的资源
修改Handler中post的Runnable逻辑,先判断Fragment是否还依附于Activity、控件是否还存在:handler.post(new Runnable() { @Override public void run() { // 先加状态判断,不符合直接返回 if (!isAdded() || getActivity() == null || niftyAuto == null || niftyAutoCalc == null || niftyAutoPers == null) { return; } niftyAuto.setText(bn); niftyAutoCalc.setText(df.format(val)); niftyAutoPers.setText("( " + df.format(persent) + "% )"); if (val > 0) { niftyAutoPers.setBackgroundResource(R.drawable.gain_indices); // 也可以用ContextCompat兼容低版本,同时用View的Context降低空指针风险 niftyAutoCalc.setTextColor(ContextCompat.getColor(niftyAutoCalc.getContext(), R.color.green)); } else { niftyAutoPers.setBackgroundResource(R.drawable.loss_indices); niftyAutoCalc.setTextColor(ContextCompat.getColor(niftyAutoCalc.getContext(), R.color.red)); } } });同时在调用
refresh(1000)之前也加同样的状态校验,避免Fragment销毁后还继续发起定时任务。Fragment销毁时主动清理所有待执行任务,从根源避免无效任务执行
重写Fragment的onStop或onDestroyView方法,清理Handler回调、中断后台线程:@Override public void onStop() { super.onStop(); // 移除Handler中所有待执行的回调和消息 handler.removeCallbacksAndMessages(null); // 中断TickData后台线程 if (tickDataThread != null && tickDataThread.isAlive()) { tickDataThread.interrupt(); } // 如果有OkHttp请求的引用,也可以同时取消请求减少资源浪费 }
内容的提问来源于stack exchange,提问作者Techno World
相关产品推荐
相关产品推荐

