如何广播Receiver和MVVM?
how to broadcast Receiver and MVVM?
我的清单
<receiver android:name=".ui.receiver.NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
和 NetworkChangeReceiver Class
class NetworkChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val connMgr = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = connMgr.activeNetworkInfo
val isConnected: Boolean? = activeNetwork?.isConnected
if(isConnected == null) {
Timber.d("Test Checked is Connected null ")
} else {
Timber.d("Test Checked Network is Connected !! ")
}
}
}
我要检测这里的网络。
如果我的 mainViewModel 检测到我在这里检测到的内容,我正在尝试调出图像,但我不知道该怎么做
正在使用实时数据可视化图像,如果此处的网络发生变化,我想更改图像在我的 MainView 模型中的可见性。
使用你的 Application
class。要么在其中包含 LiveData
,要么引用共享的 ViewModel
。
您可以使用 context.getApplicationContext()
从 NetworkChangeReceiver
访问 Application
- 为 BroadcastReceiver 的 LiveData 定义基础 class
public class ReceiverLiveData<T> extends LiveData<T> {
private final Context context;
private final IntentFilter filter;
private final BiFunction<Context, Intent, T> mapFunc;
public ReceiverLiveData(Context context, IntentFilter filter, BiFunction<Context, Intent, T> mapFunc) {
this.context = context;
this.filter = filter;
this.mapFunc = mapFunc;
}
@Override
protected void onInactive() {
super.onInactive();
context.unregisterReceiver(mBroadcastReceiver);
}
@Override
protected void onActive() {
super.onActive();
setValue(mapFunc.apply(context, new Intent()));
context.registerReceiver(mBroadcastReceiver, filter);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setValue(mapFunc.apply(context, intent));
}
};
}
- 在 ViewModel 中声明您的变量,例如电池更换意图
public static class ViewModel extends AndroidViewModel {
public final LiveData<Intent> batteryIntentLiveData = new ReceiverLiveData<>(getApplication(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED), (context, intent) -> intent);
public final LiveData<NetworkInfo> activeNetworkInfoLiveData = new ReceiverLiveData<>(getApplication(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION), ((context, intent) -> ((ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo()));
public ViewModel(@NonNull Application application) {
super(application);
}
}
- 在 Activity::onCreate
中初始化 ViewModel
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
binding.setViewModel(new ViewModelProvider(this).get(ViewModel.class));
binding.setLifecycleOwner(this);
setContentView(binding.getRoot());
}
- 在您的数据绑定布局中使用 batteryIntentLiveData 和 activeNetworkInfoLiveData
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.xxx.receiverbindingtest.MainActivity.ViewModel" />
<import type="android.os.BatteryManager" />
<import type="android.view.View" />
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.batteryIntentLiveData.getIntExtra(BatteryManager.EXTRA_LEVEL, 0))}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{viewModel.batteryIntentLiveData.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0 ? "Charging" : "Discharging"}' />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{String.valueOf(viewModel.activeNetworkInfoLiveData.state)}'
android:visibility="@{viewModel.activeNetworkInfoLiveData.connectedOrConnecting ? View.VISIBLE : View.GONE}" />
</LinearLayout>
</layout>
我的清单
<receiver android:name=".ui.receiver.NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
和 NetworkChangeReceiver Class
class NetworkChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val connMgr = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = connMgr.activeNetworkInfo
val isConnected: Boolean? = activeNetwork?.isConnected
if(isConnected == null) {
Timber.d("Test Checked is Connected null ")
} else {
Timber.d("Test Checked Network is Connected !! ")
}
}
}
我要检测这里的网络。
如果我的 mainViewModel 检测到我在这里检测到的内容,我正在尝试调出图像,但我不知道该怎么做
正在使用实时数据可视化图像,如果此处的网络发生变化,我想更改图像在我的 MainView 模型中的可见性。
使用你的 Application
class。要么在其中包含 LiveData
,要么引用共享的 ViewModel
。
您可以使用 context.getApplicationContext()
从 NetworkChangeReceiver
Application
- 为 BroadcastReceiver 的 LiveData 定义基础 class
public class ReceiverLiveData<T> extends LiveData<T> {
private final Context context;
private final IntentFilter filter;
private final BiFunction<Context, Intent, T> mapFunc;
public ReceiverLiveData(Context context, IntentFilter filter, BiFunction<Context, Intent, T> mapFunc) {
this.context = context;
this.filter = filter;
this.mapFunc = mapFunc;
}
@Override
protected void onInactive() {
super.onInactive();
context.unregisterReceiver(mBroadcastReceiver);
}
@Override
protected void onActive() {
super.onActive();
setValue(mapFunc.apply(context, new Intent()));
context.registerReceiver(mBroadcastReceiver, filter);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setValue(mapFunc.apply(context, intent));
}
};
}
- 在 ViewModel 中声明您的变量,例如电池更换意图
public static class ViewModel extends AndroidViewModel {
public final LiveData<Intent> batteryIntentLiveData = new ReceiverLiveData<>(getApplication(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED), (context, intent) -> intent);
public final LiveData<NetworkInfo> activeNetworkInfoLiveData = new ReceiverLiveData<>(getApplication(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION), ((context, intent) -> ((ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo()));
public ViewModel(@NonNull Application application) {
super(application);
}
}
- 在 Activity::onCreate 中初始化 ViewModel
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
binding.setViewModel(new ViewModelProvider(this).get(ViewModel.class));
binding.setLifecycleOwner(this);
setContentView(binding.getRoot());
}
- 在您的数据绑定布局中使用 batteryIntentLiveData 和 activeNetworkInfoLiveData
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.xxx.receiverbindingtest.MainActivity.ViewModel" />
<import type="android.os.BatteryManager" />
<import type="android.view.View" />
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.batteryIntentLiveData.getIntExtra(BatteryManager.EXTRA_LEVEL, 0))}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{viewModel.batteryIntentLiveData.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0 ? "Charging" : "Discharging"}' />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{String.valueOf(viewModel.activeNetworkInfoLiveData.state)}'
android:visibility="@{viewModel.activeNetworkInfoLiveData.connectedOrConnecting ? View.VISIBLE : View.GONE}" />
</LinearLayout>
</layout>