Redberry Redberry - 1 year ago 95
Android Question

MVVM databinding when model is updated by service

SOLVED! See below for final solution

I am trying to use databinding and MVVM for an android app but the problem lies in the fact that the model is updated by a service that is separate from the MVVM part of the app.
If I update the model via the viewmodel it works fine, but I can't seem to work out a clean way of getting a change to the model to bubble up to the viewmodel and then to the view when the model is updated by the service.

The App:
The app connects to an external device via bluetooth and then maintains a serial connection where sensor readings and settings are streamed continuously from the device to the app in close to real-time. Commands can also be sent to the device via this connection.
The model acts as an in-memory representation of the device. Different screens in the app expose different sections of the model to the user and may or may not allow them to adjust certain values (settings).

Code: (I can't show my exact code but here is a simplified version)


public class DeviceModel extends BaseObservable {

private int mode;

public int getMode(){
return mode;

public void setMode(int mode) {
this.mode = mode;


public class BasicViewViewModel extends BaseObservable {
private final Context mContext;
private ObservableField<DeviceModel> modelFields;

public BasicViewViewModel(Context context){
mContext = context.getApplicationContext();
ApplicationBase app = ApplicationBase.getInstance();
modelFields = new ObservableField<>(app.dModel);

public String getMode(){
return modelFields.get().Mode;


public class BasicViewFragment extends Fragment {
private FragmentBasicViewBinding mBinding;
private BasicViewViewModel mViewModel;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
mViewModel = new BasicViewViewModel(getContext());
mBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_basic_view, container, false);
View view = mBinding.getRoot();
return view;


<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="">
<variable name="device" type=""/>

android:id="@+id/tvModeVal" />


Custom Application Code:

public class ApplicationBase extends Application {

private static ApplicationBase instance;
public BluetoothCommsService btComms;
public DeviceModel dModel;

public void onCreate(){
instance = this;
dModel = new DeviceModel();
btComms = new BluetoothCommsService();


public static ApplicationBase getInstance(){
return instance;

In the end I followed @exkoria 's advice and used EventBus to create and send a custom event:

public class DeviceModelUpdateEvent {

public final String fieldName;
public final String newValue;

public DeviceModelUpdateEvent(String field, String value){
fieldName = field;
newValue = value;

The I put a handler in my viewmodel to trigger the databinding update in the view:

public void onMessageEvent(DeviceModelUpdateEvent event){
case "yieldLevel":
case "mode":
case "deviceType":
case "firmwareVersion":

Answer Source

Can't you just add a listener to your model so your viewmodel can listen for changes in the model and update the view when changes occur? Or perhaps it's a nice usage for an event bus such as this one:

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download