平时的Android开发中,我们经常要在Fragment中去获取当前的Activity实例,刚开始的时候可能使用使用Fragment提供的getActivity
方法来获取,但是这个方法可能返回null
,为了让程序可以正常运行,项目中就出现大量下面这样的代码:
FragmentActivity activity = getActivity();
if(activity == null){
return;
}
//use activity
或
FragmentActivity activity = getActivity();
if(activity != null){
//use activity
}
这个代码是安全的,但是多次编写就显得繁琐且可能出错(因为我觉得再简单的事只要重复非常多遍,出错的可能性就增加)。
本文分场景分别介绍几种优化的方式。
Activity一定存在的场合
首先是比较简单的Activity一定存在的场合,比如Fragment的onResume
、onCreateDialog
等方法中,这里Activity不可能为空,那么如果还要加if语句来检查Activity为空的情况,就显得很多余。这种情况下我们就可以利用requireActivity
方法,这个方法的内部实现检查Activity不存在的时候会抛出异常,如果返回,一定不为空,这样就不需要再对返回值做检查:
FragmentActivity activity = requireActivity();
//use activity
Activity可能不存在的场合
Activity可能不存在的场合就分很多种,比如Fragment中另起线程、Presenter对Fragment的调用、其他组件比如播放器的回调等等,这种情况下一遍遍地去编写getActivity
结果的检测,是一件很无聊的事情,但这个又是一件必要的事情,因为如果不做就会导致程序崩溃。因此,下面提出一种将这个过程简化的方法。
首先,自己项目中应该有类似BaseFragment
、BaseDialogFragment
这样的基础Fragment,我们要做的就是在这些类里添加一个optActivity
方法,实现如下:
public Optional<FragmentActivity> optActivity() {
return Optional.ofNullable(getActivity());
}
这样在各个Fragment子类中就可以直接使用optActivity
来更加简洁地获取Activity实例:
optActivity().ifPresent(activity -> {
//do something
});
看上去和原来的代码量差不多,但只要写一遍就能体会出来,这种新的写法要素更少,更不容易出错,写起来也更快,而且在有时候可以写得更简洁、更突出重点:
button.setOnClickListener(v -> optActivity().ifPresent(activity -> {
//do something
}));
这里的重点在于按钮点击后的处理,检查Activity是否存在没那么重要。