Android中EditText调用setText()触发NullPointerException问题排查
解决EditText setText()触发NullPointerException的问题
兄弟,我一眼就看穿你这个空指针的根源了——你在Fragment还没完成视图初始化的时候,就急着调用它的setMessage()方法了!这时候etMessage还没被findViewById赋值,完全是个null对象,调用setText()可不就炸了嘛。
问题出在哪?
看你Activity的onCreate逻辑:
- 创建Fragment并调用
commit()提交事务 - 紧接着就调用
editTodoFragment.setMessage(message)
但Fragment的事务提交是异步执行的!你调用commit()之后,Fragment的onCreateView不会立刻执行,etMessage还是null状态,这时候去调用setText(),空指针异常必然找上门。
给你两个靠谱的解决方案
方案1:强制立刻执行Fragment事务(快速修复)
在commit()之后,调用executePendingTransactions()强制FragmentManager立刻执行所有待处理的事务,这样Fragment的视图会马上初始化,etMessage就能被正确赋值了:
if (fragment == null){ editTodoFragment = new EditTodoFragment(); fm.beginTransaction() .add(R.id.contentFrameContainer, editTodoFragment) .commit(); // 新增这行,强制立刻完成事务 fm.executePendingTransactions(); editTodoPresenter = new EditTodoPresenter(editTodoFragment); } // 现在再调用setMessage就安全了 editTodoFragment.setMessage(message);
方案2:通过Bundle传递数据(更符合Android规范)
更好的做法是把要设置的文本通过Fragment的参数传递,让Fragment自己在视图初始化完成后处理,这样能完全规避生命周期异步的问题:
- 给Fragment添加一个静态创建方法,用来传递参数:
public static EditTodoFragment newInstance(String message) { EditTodoFragment fragment = new EditTodoFragment(); Bundle args = new Bundle(); args.putString("TODO_MESSAGE", message); fragment.setArguments(args); return fragment; }
- 在Fragment的
onViewCreated方法里取出参数并设置文本:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (getArguments() != null) { String message = getArguments().getString("TODO_MESSAGE"); setMessage(message); } }
- 修改Activity里创建Fragment的代码:
if (fragment == null){ // 用newInstance传递message参数 editTodoFragment = EditTodoFragment.newInstance(message); fm.beginTransaction() .add(R.id.contentFrameContainer, editTodoFragment) .commit(); editTodoPresenter = new EditTodoPresenter(editTodoFragment); } // 这里不用再调用setMessage了
关于那个强制转换的提示
你提到的“强制转换为EditText是多余的”提示,和空指针问题完全没关系!这只是Android Studio的语法优化提示——从Android API 26开始,findViewById会自动返回对应视图的类型,不需要手动强转了,你直接写成etMessage = view.findViewById(R.id.etMessage);就行,不影响功能。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

