android - 片段组件在方向更改时为空
问题描述
我的游戏配置文件活动收到带有传入 id 的意图,然后我使用该 id 从我的 firebase 数据库请求具有该 id 的游戏,并且只有当找到游戏时,我才会在片段中设置其信息。
这是我请求然后将 _Game 对象添加到我的片段的方式(为简洁起见省略了代码,通常我添加了所有 ChildEventListener 方法)
public void findGameById(final int id) {
mGamesRef.orderByChild("id")
.equalTo(id)
.limitToFirst(1)
.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
_Game game = dataSnapshot.getValue(_Game.class);
mGameInfoFragment.setGameInfo(game);
}
});
}
当然,作为参数传递的 id 是从意图中获得的 id。findGameById(int id)
在活动的 OnCreate 中调用
我GameInfoFragment
在setGameInfo(_Game game)
哪里
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_game_info, container, false);
String dateFormat = SharedPrefManager.read(SharedPrefManager.KEY_PREF_REGION, getString(R.string.default_date_format));
mDateFormatter = new SimpleDateFormat(dateFormat);
mTodayTimeMillis = Calendar.getInstance().getTimeInMillis();
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Summary UI
mTextSummary = view.findViewById(R.id.summary);
mReadMore = view.findViewById(R.id.read_more);
mSummaryLoading = view.findViewById(R.id.summary_loading);
}
public void setGameInfo(_Game game) {
// Stop/hide all ongoing progress bars (loading)
mSummaryLoading.setVisibility(View.GONE);
}
在我改变方向之前一切都很好,因为在改变方向时它会给我以下错误:
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.ProgressBar.setVisibility(int)”
解决方案
默认情况下,Android 框架会在配置更改时销毁片段并重新创建它。如果您没有自己处理配置更改,那么您的片段已被重新创建。这个对片段的引用
mGameInfoFragment.setGameInfo(game);
可能不再有效,因此出现 NullPointerException。根据经验,不要存储对具有生命周期的对象的引用,例如活动和片段,因为它们是易失性的并且可能导致内存泄漏(您的就是内存泄漏的一个例子,系统无法释放您的旧片段,因为您仍然有一个参考它)。
一种方法是自己处理方向变化。在这里进一步阅读
android:configChanges="orientation"
另一种方法是确保在调用方法之前始终获得框架膨胀和显示的片段。
推荐阅读
- kubernetes - 重复的大使映射是否会导致 Kubernetes 服务失效?
- r - 如何删除R中的匹配字符?
- php - PHP HTTP 500 试图从 api 发出 GET 请求
- mysql - 重新启动 docker 时表和记录丢失
- python-3.x - 在 ubuntu 中避免使用 /run/user 类型的路径
- java - 如何将 2 个独立列表转换为单个列表
- react-native - 在 TabBar 中的按钮中更改屏幕
- c# - 如何将异步 IO 任务的数量限制到数据库?
- c# - 存储和重用条件表达式
- c# - 'System.ArgumentOutOfRangeException' 类型的异常附加信息:索引超出范围