【问题标题】:BroadcastReceiver in order to pass data from another Activity to FragmentBroadcastReceiver 以便将数据从另一个 Activity 传递到 Fragment
【发布时间】:2015-12-23 19:53:55
【问题描述】:

假设我有 MainActivity,其中 ViewPager 中的片段很少。我想将数据从另一个 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);
    }
}

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

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

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

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

【问题讨论】:

  • 您可以使用LocalBroadcastManager 而不是BroadcastReceiver 进行内部组件通信
  • 但我的做法是个好方法?
  • 你可以在你的activity和fragment之间建立一个接口。如果您有兴趣,我可以发布一个示例。
  • 我很感兴趣:)

标签: android android-fragments android-activity broadcastreceiver


【解决方案1】:

另一种方法是使用接口在您的活动和片段之间进行通信。示例:

界面

public interface MyInterface {

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

}

活动

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();

    }

}

您可以使用该接口在一个或多个活动、多个片段、视图、任务、服务等之间进行通信。如果您要走这条路,我将创建一个实现 MyInterface 及其方法的基础活动,并让所有其他活动扩展基本活动。我什至会创建一个调用 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,基本片段已经有它的公共实例。您只需通过您的界面设置/获取/等,无需任何额外的大惊小怪:

mi.setSomeValue(20);

【讨论】:

  • MainActivity 创建 Fragment1,SecondActivity 创建 Fragment2。我想将数据或调用方法从 Fragment2 传递到 Fragment1。但是使用您的代码(如果我理解正确的话)Fragment2 在 onAttach 方法中获得 SecondActivity。
  • 是的,这就是为什么使用实现接口的基本活动和附加接口的基本片段来设置您的应用程序的原因。一旦你有了它,你就可以将任何数据从/传递到任何类。如果处理得当,您甚至不需要在片段之间传递任何 Bundle 数据。
【解决方案2】:

我会改用 LocalBroadcastManager,它为您提供以下优势:

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

这个直接来自官方docs

【讨论】:

    【解决方案3】:

    您可以使用 Extras 传递数据。

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

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

    String data_needed_here= extras.getString("STRING_YOU_NEED");

    【讨论】:

    • 我知道,但问题是有没有比广播接收器更好的数据传递方法
    • 您不需要编写广播接收器。您可以简单地检查 getIntent().getExtras 是否返回 viewCreated 内的任何数据并存储是否有值
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 2017-04-05
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多