概述
每个Activity或者Fragment中需要完成自己的一些功能,但是通常也需要和其他Activity或者Fragment进行交互,这时候就涉及到了它们之间通讯的一些常用方法。这篇文章,从Activity之间、Activity和Fragment之间、Fragment之间这三种情况总结常用的通讯方式。
Activity之间
通过Intent传输数据
在使用startActivity(Intent)跳转Activity的时候,传递一个Intent对象携带数据信息,但值得注意的是,Intent支持的数据类型,以及传递过大的对象时候(不能超过IM)可能会报TransactionTooLargeException异常,源码层次分析可见探究Intent传递大小限制
替代方案有:
- 写入临时文件或者数据库,通过FileProvider将该文件或者数据库通过Uri发送至目标。
- 使用静态变量。但是需要注意判空。因为由于系统内存不足时,可能会回收静态变量。
Intent支持传递的数据类型
以一种key-value的形式,传递数据
- Java八种基本数据类型:boolean、byte、char、short、int、float、double、long
- 八种基本类型的数组格式
- String、CharSequence
- Serializable、Parcelable
- Bundle
Activity和Fragment之间、Fragment之间
Fragment之间的通信,不建议采用Fragment直接通信的方式,因为Fragment的提出就是为了复用,那样会增加耦合度,不利于复用,所以一般是通过Activity作为消息的中转站进行通信。所以下面就重点记录Activity和Fragment通信的方式。
Activity向Fragment传递消息
第一种方法:
由于Activity中本来就持有fragment的对象引用,可以直接调用fragment中的方法传递消息;
第二种方法:
利用Bundle进行传值,其实这个跟第一种也差不多,在Activity中调用fragment.setArguments(Bundle)
,然后在Fragment中就可以通过getArguments
获得Bundle对象;
Fragment向Activity传递消息
官方推荐是通过接口回调进行消息的传递。在Fragment中定义一个接口,然后Activity实现该接口,这样就可以实现Fragment发送消息,Activity响应的效果,例如:
// fragment的代码
public class ForthFragment extends Fragment {
public static ForthFragment newInstance() {
return new ForthFragment();
}
private Handler mHandler;
private OnCallbackListner mListener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnCallbackListner){
mListener = (OnCallbackListner) context;
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.forth_fragment, container, false);
}
interface OnCallbackListner {
void callback(Object object);
}
}
public class ForthActivity extends AppCompatActivity implements ForthFragment.OnCallbackListner{
private ForthFragment forthFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.forth_activity);
initView();
initData();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, forthFragment = ForthFragment.newInstance())
.commitNow();
}
}
private void initView() {
//TODO view的初始化
}
private void initData() {
// TODO 处理数据
}
@Override
public void callback(Object object) {
// 处理回调。。。
}
}
但是采用这样的方式,当接口增多的时候,会很爆炸。。。
那么如何更加优雅的采用接口回调的方式传递消息呢?这时候就需要一个万能接口。Activity和Fragment通信的万能接口
利用Handler进行消息的传递
Fragment和Activity持有对方的Handler引用,这样就可以双方发送消息了。参考这篇文章