具有2个Observable的Android可观察模式

时间:2022-05-26 21:05:46

Inside my activity I have a broadcast receiver that I initialize as such:

在我的活动中,我有一个广播接收器,我初始化如下:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        updateViews();
    }
};

updateViews() is a function inside the activity that is only used within the broadcast receiver. How can I create this receiver as a separate class that can play with the views (rotate, delete etc.) of my activity?

updateViews()是活动内部的一个功能,仅在广播接收器中使用。如何创建此接收器作为一个单独的类,可以播放我的活动的视图(旋转,删除等)?

In addition, I have a compass within the activity. It works, however I would also like to make the compass a separate class that can send data to the activity. It will not change the views of the activity but only update certain double/float values.

另外,我在活动中有一个指南针。它的工作原理,但我还想让指南针成为一个可以将数据发送到活动的独立类。它不会更改活动的视图,只会更新某些double / float值。

@Override
public void onSensorChanged(SensorEvent event) {    }

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {    }

1 个解决方案

#1


0  

How can I create this receiver as a separate class...?

如何将此接收器创建为单独的类......?

This answer assumes that "separate class" means you want a BroadcastReceiver that is defined in its own source file and is not an inner class of an activity. Before offering a solution, I'll ask, what do you expect to gain by this? Do you have multiple activities that will use the receiver? If not, it's best to leave it as an inner class of the single activity that uses it. If you don't like using the anonymous inner class in the code you posted, you can declare is as an inner class:

这个答案假定“单独的类”意味着您需要一个在其自己的源文件中定义并且不是活动的内部类的BroadcastReceiver。在提供解决方案之前,我会问,你期望从中得到什么?你有多个活动将使用接收器吗?如果没有,最好将其作为使用它的单个活动的内部类。如果您不喜欢在发布的代码中使用匿名内部类,则可以声明为内部类:

private class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // As an inner class of the activity, this receiver has
        // access to all activity members.
        updateViews();
    }
}

If you really want it as a standalone receiver, the example code below is a starting point. Be sure to register/unregister the receiver in your activity's onResume/onPause callbacks. The example includes code for a less safe approach, using a plain activity reference, and a safer approach using a weak reference. Only one is needed.

如果您真的希望它作为独立的接收器,下面的示例代码是一个起点。务必在活动的onResume / onPause回调中注册/取消注册接收器。该示例包括使用普通活动引用的不太安全的方法的代码,以及使用弱引用的更安全的方法。只需要一个。

public class MyBroadcastReceiver extends BroadcastReceiver {
    // For less safe use
    private MyClientActivity mActivity;
    // For more safe use
    private WeakReference<MyClientActivity> mActivityRef;

    public MyBroadcastReceiver(MyClientActivity activity) {
        mActivity = activity;
        mActivityRef = new WeakReference<MyClientActivity>(activity);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // Less safe
        mActivity.findViewById(R.id.action_bar);
        mActivity.someActivityMemberMethod();
        // etc

        // More safe.  Guards against failure to unregister
        // this receiver when activity is paused.
        MyClientActivity act = mActivityRef.get();
        if (act != null && !act.isDestroyed()) {
            mActivity.findViewById(R.id.action_bar);
            mActivity.someActivityMemberMethod();
            // etc
        } else {
            // Error: Activity failed to unregister this receiver
        }
    }
}

I would also like to make the compass a separate class that can send data to the activity

我还想使指南针成为可以将数据发送到活动的单独类

Same assumption and question as above: Will the compass be used by multiple activities? If not, it's probably best to make it an inner class of the single activity. If there are multiple client activities, consider using a started-service. It could notify activities of sensor events using a local broadcast or an event bus such as greenrobot.

与上述相同的假设和问题:指南针是否会被多个活动使用?如果没有,最好将它作为单一活动的内部类。如果有多个客户端活动,请考虑使用启动服务。它可以使用本地广播或诸如greenrobot之类的事件总线来通知传感器事件的活动。

#1


0  

How can I create this receiver as a separate class...?

如何将此接收器创建为单独的类......?

This answer assumes that "separate class" means you want a BroadcastReceiver that is defined in its own source file and is not an inner class of an activity. Before offering a solution, I'll ask, what do you expect to gain by this? Do you have multiple activities that will use the receiver? If not, it's best to leave it as an inner class of the single activity that uses it. If you don't like using the anonymous inner class in the code you posted, you can declare is as an inner class:

这个答案假定“单独的类”意味着您需要一个在其自己的源文件中定义并且不是活动的内部类的BroadcastReceiver。在提供解决方案之前,我会问,你期望从中得到什么?你有多个活动将使用接收器吗?如果没有,最好将其作为使用它的单个活动的内部类。如果您不喜欢在发布的代码中使用匿名内部类,则可以声明为内部类:

private class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // As an inner class of the activity, this receiver has
        // access to all activity members.
        updateViews();
    }
}

If you really want it as a standalone receiver, the example code below is a starting point. Be sure to register/unregister the receiver in your activity's onResume/onPause callbacks. The example includes code for a less safe approach, using a plain activity reference, and a safer approach using a weak reference. Only one is needed.

如果您真的希望它作为独立的接收器,下面的示例代码是一个起点。务必在活动的onResume / onPause回调中注册/取消注册接收器。该示例包括使用普通活动引用的不太安全的方法的代码,以及使用弱引用的更安全的方法。只需要一个。

public class MyBroadcastReceiver extends BroadcastReceiver {
    // For less safe use
    private MyClientActivity mActivity;
    // For more safe use
    private WeakReference<MyClientActivity> mActivityRef;

    public MyBroadcastReceiver(MyClientActivity activity) {
        mActivity = activity;
        mActivityRef = new WeakReference<MyClientActivity>(activity);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // Less safe
        mActivity.findViewById(R.id.action_bar);
        mActivity.someActivityMemberMethod();
        // etc

        // More safe.  Guards against failure to unregister
        // this receiver when activity is paused.
        MyClientActivity act = mActivityRef.get();
        if (act != null && !act.isDestroyed()) {
            mActivity.findViewById(R.id.action_bar);
            mActivity.someActivityMemberMethod();
            // etc
        } else {
            // Error: Activity failed to unregister this receiver
        }
    }
}

I would also like to make the compass a separate class that can send data to the activity

我还想使指南针成为可以将数据发送到活动的单独类

Same assumption and question as above: Will the compass be used by multiple activities? If not, it's probably best to make it an inner class of the single activity. If there are multiple client activities, consider using a started-service. It could notify activities of sensor events using a local broadcast or an event bus such as greenrobot.

与上述相同的假设和问题:指南针是否会被多个活动使用?如果没有,最好将它作为单一活动的内部类。如果有多个客户端活动,请考虑使用启动服务。它可以使用本地广播或诸如greenrobot之类的事件总线来通知传感器事件的活动。