如何在片段中设置广播监听器接口?

How to set broadcast listener interface in fragment?

我有服务,它从 API 获取数据并将此数据发送到 BroadcastReceiver class。另外,我创建了在 Activity 中使用的接口 OnReceiveListener。看这里的代码:

Activity:

public class StartActivity extends AppCompatActivity
    implements MyBroadcastReceiver.OnReceiveListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);

    MyBroadcastReceiver receiver = new MyBroadcastReceiver();
    receiver.setOnReceiveListener(this);
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
            new IntentFilter(MyBroadcastReceiver.START));
    ...
}

@Override
public void onReceive(Intent intent) {
    // Do smth here
}
}

MyBroadcastReceiver:

public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String START = "com.example.myapp.START";
public static final String GET_LINKS = "com.example.myapp.GET_LINKS";

private OnReceiveListener onReceiveListener = null;

public interface OnReceiveListener {
    void onReceive(Intent intent);
}

public void setOnReceiveListener(Context context) {
    this.onReceiveListener = (OnReceiveListener) context;
}

@Override
public void onReceive(Context context, Intent intent) {
    if(onReceiveListener != null) {
        onReceiveListener.onReceive(intent);
    }
}
}

这个问题服务不重要。

----问题----

所以,有什么问题:我想在片段中使用这个接收器,但是当它设置上下文时 - 我得到异常 "enable to cast"。这种情况我该怎么办?

这是我的片段代码:

public class MainFragment extends Fragment
    implements MyBroadcastReceiver.OnReceiveListener {

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    myBroadcastReceiver.setOnReceiveListener(getContext());
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
            new IntentFilter(MyBroadcastReceiver.GET_LINKS));
}

@Override
public void onReceive(Intent intent) {
    // Do smth here
}
}

您的 MainFragment class 实现了您的 OnReceiveListener 接口,而不是 getContext() 返回的 Context。不要将 Context 对象传递给 setOnReceiveListener(),而是尝试直接传递 OnReceiveListener 实例。然后你的片段和 activity 都可以调用 setOnReceiveListener(this).

您不需要动态注册接收器。我相信您一定已经使用 <receiver> 标签在清单中注册了它。

这不是必需的:

LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver, new IntentFilter(MyBroadcastReceiver.GET_LINKS));

关于回调注册侦听器,而不是使用 getContext() 使用 MainFragment.this 像这样:

myBroadcastReceiver.setOnReceiveListener(MainFragment.this);

在搜索了数小时以寻找适当的方法来实现此问题的这种解决方案之后,我终于找到了一种方法。它基于 RussHWolf 的回答。带有代码的完整解决方案如下:

这样就暴露了一个setListener()方法,这样Fragment或者Activity就可以通过发送IStatusChangeListener.[=24=的实例来设置监听器]

public class StatusChangeReceiver extends BroadcastReceiver {
    private IStatusChangeListener listener;

    public void setListener(IStatusChangeListener listener) {
        this.listener = listener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (NetworkUtil.isNetworkConnected()) {
            listener.onConnected();
        } else {
            listener.onDisconnected();
        }
    }
}

这是界面:

public interface IStatusChangeListener {
    void onConnected(String status);
    void onDisonnected(String status);
}

现在,需要有一个 IStatusChangeListener 接口的实例,而不是实现 IStatusChangeListener 接口。然后,将 IStatusChangeListener 的这个实例传递给 setListener() 方法。

public class MainFragment extends Fragment { //Not implementing the interface

    private IStatusChangeListener listener = new IStatusChangeListener() {
        @Override
        void onConnected(String status) {
            //some log here
        }

        @Override
        void onDisonnected(String status) {
            //some log here
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        StatusChangeReceiver r = new StatusChangeReceiver();
        r.setListener(listener); // pass the IStatusChangeListener instance
        LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
    }
}

注意:如果您从 Fragment.

注册 BroadcastReceiver,请始终使用 LocalBroadcastManager