Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

android - Proper way to update LiveData from the Model?

The "proper" way to update views with Android seems to be LiveData. But I can't determine the "proper" way to connect that to a model. Most of the documentation I have seen shows connecting to Room which returns a LiveData object. But (assuming I am not using Room), returning a LiveData object (which is "lifecycle aware", so specific to the activity/view framework of Android) in my model seems to me to violate the separation of concerns?

Here is an example with Activity...

class MainActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_activity);

        val viewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        val nameText = findViewById<TextView>(R.id.nameTextBox)

        viewModel.getName().observe(this, { name ->
            nameText.value = name
        })
    }
}

And ViewModel...

class UserViewModel(): ViewModel() {
    private val name: MutableLiveData<String> = MutableLiveData()

    fun getName() : LiveData<String> {
        return name
    }
}

But how do I then connect that to my Model without putting a "lifecycle aware" object that is designed for a specific framework in my model (LiveData)...

class UserModel {
    val uid
    var name

    fun queryUserInfo() {
        /* API query here ... */
        val request = JSONObjectRequest( ...
            { response ->
                if( response.name != this.name ) {
                    this.name = response.name
                    /* Trigger LiveData update here somehow??? */
                }
            }
        )
    }
}

I am thinking I can maybe put an Observable object in my model and then use that to trigger the update of the LiveData in my ViewModel. But don't find any places where anyone else says that is the "right" way of doing it. Or, can I instantiate the LiveData object in the ViewModel from an Observable object in my model?

Or am I just thinking about this wrong or am I missing something?

question from:https://stackoverflow.com/questions/65865157/proper-way-to-update-livedata-from-the-model

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is from official documentation. Check comments in code...

From official documentation

UserModel should remain clean

class UserModel {
    private val name: String,
    private val lastName: String
}

Create repository to catch data from network

class UserRepository {
   private val webservice: Webservice = TODO()
   
   fun getUser(userId: String): LiveData<UserModel > {
       
       val data = MutableLiveData<UserModel>() //Livedata that you observe

       //you can get the data from api as you want, but it is important that you 
       //update the LiveDate that you will observe from the ViewModel 
       //and the same principle is in the relation ViewModel <=> Fragment

       webservice.getUser(userId).enqueue(object : Callback<UserModel > {
           override fun onResponse(call: Call<User>, response: Response<UserModel >) {
               data.value = response.body() 
           }
           // Error case is left out for brevity.
           override fun onFailure(call: Call<UserModel >, t: Throwable) {
               TODO()
           }
       })
       return data  //you will observe this from ViewModel
   }
}

The following picture should explain to you what everything looks like

enter image description here

For more details check this:

https://developer.android.com/jetpack/guide

viewmodels-and-livedata-patterns-antipatterns


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...