Android MVVM。生命周期感知模型是代码味道还是适当的设计?

Android MVVM. Is life-cycle aware Model a code smell or a proper design?

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

为了在不需要时不执行代码,我的模型代码当前正在订阅 onCreate() 中的 phone 连接更改,并通过实施 LifecycleObserveronDestroy() 中取消注册

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

总感觉不对。

在理想的世界中,Activity 将成为视图层(MVVM 中的 V)的一部分,并且应该只知道 viewModel,但在上述情况下,生命周期意识使 activity 也了解模型。

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

我真的很喜欢那个图案。在全局可共享对象中实现状态监听的示例是

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 来完成此操作,而这正是现在发生的事情。