BroadcastReceiver 以便将数据从另一个 Activity 传递到 Fragment

BroadcastReceiver in order to pass data from another Activity to Fragment

假设我有 MainActivity,ViewPager 中的 Fragment 很少。我想将数据从另一个 Activity 传递到这些片段之一。我正在通过 BroadcastReceiver 执行此操作。

public class MyFragment extends Fragment {

    private MyFragmentReceiver mReceiver;

    public MyFragment() {
        super();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReceiver = new MyFragmentReceiver();
        getActivity().registerReceiver(mReceiver, new IntentFilter("fragmentUpdater"));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_my, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // My code here
    }

    public class MyFragmentReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //My methods
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mReceiver != null)
            getActivity().unregisterReceiver(mReceiver);
    }
}

所以在我的另一个Activity中我正在做这样的事情:

Intent data = new Intent("fragmentUpdater");
MyApplication.getInstance().getMainActivity().sendBroadcast(data);

其中 MyApplication 是包含 MainActivity 的单例。 我注意到 BroadcastReceiver 正在将一些东西放入日志中,我想知道这是最好的方法。

  1. 是否有更好的方法将数据从另一个 activity 传递到特定 Fragment 或调用该 Fragment 中的方法?
  2. 我是否必须在 AndroidManifest.xml 中包含与 BroadcastReceiver 相关的内容?

您可以使用 Extras 传递数据。

意图数据=新意图("fragmentUpdater"); data.putExtra("STRING_YOU_NEED", strName);

并且您可以通过以下方式获取 onReceive 函数中的数据:

字符串data_needed_here=extras.getString("STRING_YOU_NEED");

我会改用 LocalBroadcastManager,它具有以下优势:

  • 你知道你正在广播的数据不会离开你的应用程序,所以 不用担心隐私数据泄露。
  • 其他应用程序无法发送这些广播 到您的应用程序,因此您无需担心存在安全漏洞 他们可以利用。
  • 比通过系统发送全球广播更高效

直接来自官方docs

一种替代方法是使用一个接口在您的 activity 和片段之间进行通信。示例:

界面

public interface MyInterface {

    void setSomeValue(int someValue);
    int getSomeValue();

}

Activity

public class MyActivity extends Activity implements MyInterface {

    private int someValue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // do the usual stuff
    }

    // implement from MyInterface
    @Override
    public void setSomeValue(int someValue) {
        this.someValue = someValue;
    }

    // implement from MyInterface
    @Override
    public int getSomeValue() {
        return someValue;
    }

}

片段

public class MyFragment extends Fragment {

    private MyInterface mi;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mi = (MyInterface) context;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) {

        mi.setSomeValue(20);
        int someValue = mi.getSomeValue();

    }

}

您可以使用该接口在一个或多个活动、多个片段、视图、任务、服务等之间进行通信。如果您要走这条路,我会创建一个基础 activity实现 MyInterface 及其方法,并让所有其他活动扩展基础 activity。我什至会创建一个调用 onAttach() 的基本片段,并让我的所有其他片段扩展这个基本片段(这样我就不需要在每个片段中调用 onAttach())。

更新...

基本片段看起来像这样:

public class BaseFragment extends Fragment {

    public MyInterface mi;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mi = (MyInterface) context;
    }

}

现在,MyFragment 只会扩展 BaseFragment...

public class MyFragment extends BaseFragment {
    ...
}

现在不需要在任何扩展 BaseFragment 的片段中附加甚至声明 MyInterface,基本片段已经有它的 public 实例。您只需 set/get/etc 通过您的界面,无需任何额外的麻烦:

mi.setSomeValue(20);