-1

对于我的活动,我需要知道手机的连接状态。由于这是我的 UI 需要响应的数据,因此它属于MVVM的模型领域(如果您不同意,请告诉我)。

为了在不需要时不执行代码,我的模型代码目前正在通过实现订阅电话连接更改onCreate()和注销onDestroy()LifecycleObserver

为此,我在 Activity 代码中使用 viewModel 实例化并连接我的模型。

怎么感觉都不对。

在理想情况下,Activity 将是 View 层(MVVM 中的 V)的一部分,并且应该只知道 viewModel,但在上述情况下,生命周期感知使 Activity 也知道 Model。

那么,生命周期感知模型是一个合适的概念吗?还是我应该重新考虑设计?

4

1 回答 1

3

我真的很喜欢那种模式。在全局共享对象中实现状态监听的一个例子是

public class WifiState {
    private static WifiState instance;
    public static synchronized WifiState getInstance(Context context) {
        if (instance == null) instance = new WifiState(context.getApplicationContext());
        return instance;
    }

    private final Context context;
    private final WifiManager wm;
    private WifiState(Context context) {
        this.context = context;
        wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    }

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
            wifiStateLiveData.setValue(state);
        }
    };

    public LiveData<Integer> wifiState() { return wifiStateLiveData; }

    private final MutableLiveData<Integer> wifiStateLiveData = new MutableLiveData<Integer>() {

        @Override
        protected void onActive() {
            setValue(wm.getWifiState()); // update immediately
            context.registerReceiver(receiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
        }
        @Override
        protected void onInactive() {
            context.unregisterReceiver(receiver);
        }

        @Override
        public void setValue(Integer value) { // debounce non-change
            Integer old = getValue();
            if (old == null && value != null || old != null && !old.equals(value)) {
                super.setValue(value);
            }
        }
    };
}

这允许您一次使用来自多个地方的相同源,而无需创建多个广播接收器等的开销

public class SomeActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WifiState.getInstance(this).wifiState().observe(this, state -> {
            if (state != WifiManager.WIFI_STATE_ENABLED) {
                Toast.makeText(this, "Please enable WIFI", Toast.LENGTH_LONG);
            }
        });
    }
}

使用生命周期功能的一大优势是您不必在代码中乱扔 onStart / onStop 调用,此外,您再也不会错过 onStop 调用和泄漏接收器等问题。魔法发生在一些库中,你的代码可以变得相当简单和干净。无论您是实现LifecycleObserver还是使用LiveData,如果做得好,您最终会得到更清晰的代码。

让框架处理您的生命周期ViewModel也很好,但它并没有真正改变 MV* 模式,因为您之前以一种或另一种方式拥有 ViewModel。您可能直接计算了 Activity / Fragment 中的属性。这里的新功能是框架现在为您保留该模型的时间恰到好处。您以前可以使用保留的 Fragment 来做到这一点,而这正是现在幕后发生的事情。

于 2018-09-25T22:02:19.187 回答