Android 我应该在ViewModel中包含LifecycleOwner吗?

Android 我应该在ViewModel中包含LifecycleOwner吗?,android,mvvm,android-viewmodel,Android,Mvvm,Android Viewmodel,LifecycleOwner当前是我创建观察者所必需的 我有在ViewModel中创建观察者的代码,因此在片段中检索ViewModel时,我附加LifecycleOwner 根据谷歌的文档 警告:ViewModel决不能引用视图、生命周期或任何可能包含对活动上下文引用的类 我打破了那个警告了吗?如果我打破了,你建议我用什么方法来移动我创建的用于数据返回的观察者 我只是做了一个观察者,所以我想知道它是否仍然有效。因为谷歌的文档中也提到了这一点 ViewModel对象可以包含LifecycleObs

LifecycleOwner当前是我创建观察者所必需的

我有在ViewModel中创建观察者的代码,因此在片段中检索ViewModel时,我附加LifecycleOwner

根据谷歌的文档

警告:ViewModel决不能引用视图、生命周期或任何可能包含对活动上下文引用的类

我打破了那个警告了吗?如果我打破了,你建议我用什么方法来移动我创建的用于数据返回的观察者

我只是做了一个观察者,所以我想知道它是否仍然有效。因为谷歌的文档中也提到了这一点

ViewModel对象可以包含LifecycleObserver,例如LiveData对象

main片段

private lateinit var model: MainViewModel

/**
 * Observer for our ViewModel IpAddress LiveData value.
 * @see Observer.onChanged
 * */
private val ipObserver = Observer<String> {
    textIp.text = it
    hideProgressBar()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    model = ViewModelProviders.of(this).get(MainViewModel::class.java)
    model.attach(this)
}

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater?.inflate(R.layout.fragment_main, container, false)

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    buttonRetrieveIp.setOnClickListener {
        showProgressBar()
        model.fetchMyIp().observe(this, ipObserver) //Here we attach our ipObserver
    }
}

override fun showProgressBar() {

    textIp.visibility = View.GONE
    progressBar.visibility = View.VISIBLE
}

override fun hideProgressBar() {

    progressBar.visibility = View.GONE
    textIp.visibility = View.VISIBLE
}
private lateinit var模型:MainViewModel
/**
*查看我们的ViewModel IpAddress LiveData值。
*@see Observer.onChanged
* */
private val ipObserver=观察者{
textIp.text=it
hideProgressBar()
}
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
model=ViewModelProviders.of(this.get)(MainViewModel::class.java)
模型。附加(此)
}
覆盖创建视图(充气机:布局充气机?、容器:视图组?、savedInstanceState:捆绑?):视图=
充气机?充气(右侧布局,主容器,假)
覆盖已创建的视图(视图:view?,savedInstanceState:Bundle?){
super.onViewCreated(视图,savedInstanceState)
buttonRetrieveIp.setOnClickListener{
showProgressBar()
model.fetchMyIp().observe(this,ipObserver)//这里我们附加我们的ipObserver
}
}
覆盖有趣的showProgressBar(){
textIp.visibility=View.GONE
progressBar.visibility=View.VISIBLE
}
覆盖有趣的hideProgressBar(){
progressBar.visibility=View.GONE
textIp.visibility=View.VISIBLE
}
MainViewModel

private var ipAddress = MutableLiveData<String>()
private lateinit var owner: LifecycleOwner

fun attach(fragment: MainFragment) {
    owner = fragment
}

/**
 * For more information regarding Fuel Request using Fuel Routing and Live Data Response.
 * @see <a href="https://github.com/kittinunf/Fuel#routing-support">Fuel Routing Support</a>
 * @see <a href="https://github.com/kittinunf/Fuel#livedata-support">Fuel LiveData Support</a>
 * */
fun fetchMyIp(): LiveData<String> {

    Fuel.request(IpAddressApi.MyIp())
            .liveDataResponse()
            .observe(owner, Observer {

                if (it?.first?.statusCode == 200) {//If you want you can add a status code checker here.

                    it.second.success {

                        ipAddress.value = Ip.toIp(String(it))?.ip
                    }
                }
            })
    return ipAddress
}
private var ipAddress=MutableLiveData()
私有lateinit变量所有者:LifecycleOwner
趣味附加(片段:MainFragment){
所有者=片段
}
/**
*有关使用燃料路由和实时数据响应的燃料请求的更多信息。
*@见
*@见
* */
fun fetchMyIp():LiveData{
Fuel.request(IpAddressApi.MyIp())
.liveDataResponse()
.观察(所有者、观察员){
如果(it?.first?.statusCode==200){//如果需要,可以在此处添加状态代码检查器。
第二,成功{
ipAddress.value=Ip.toIp(字符串(it))?.Ip
}
}
})
返回IP地址
}
更新1:由于@pskink建议使用转换,改进了ViewModel。

private lateinit var ipAddress:LiveData<String>

/**
 * Improved ViewModel since January 23, 2018 credits to <a href="https://stackoverflow.com/users/2252830/pskink">pskink</a> <a href="
 *
 * For more information regarding Fuel Request using Fuel Routing and Live Data Response.
 * @see <a href="https://github.com/kittinunf/Fuel#routing-support">Fuel Routing Support</a>
 * @see <a href="https://github.com/kittinunf/Fuel#livedata-support">Fuel LiveData Support</a>
 * */
fun fetchMyIp(): LiveData<String> {

    ipAddress = Transformations.map(Fuel.request(IpAddressApi.MyIp()).liveDataResponse(), {

        var ip:String? = ""

            it.second.success {

                ip = Ip.toIp(String(it))?.ip
            }
        ip
    })

    return ipAddress
}
private lateinit var ipAddress:LiveData
/**
*自2018年1月23日起改进的ViewModel归功于
*@见
* */
fun fetchMyIp():LiveData{
ipAddress=Transformations.map(Fuel.request(IpAddressApi.MyIp()).liveDataResponse(){
变量ip:字符串?=“”
第二,成功{
ip=ip.toIp(字符串(it))?.ip
}
知识产权
})
返回IP地址
}

假设:

  • Fuel
    指的是您的
    ViewModel
  • Fuel.request(IpAddressApi.MyIp())
    是您的
    ViewModel
  • IpAddressApi.MyIp()
    没有对您的
    LifecycleOwner
    的引用
  • 如果所有这些都是真的,那么你没有违反它。只要您没有将
    LifecycleOwner
    引用传递给
    ViewModel
    您就安全了


    LifecycleOwner-与活动或片段相关,因为它拥有各种Android生命周期,例如onCreate、onPause、onDestroy等

    否。如果您希望观察
    视图模型中某些
    LiveData
    的更改,可以使用
    observeForver()
    它不需要
    生命周期所有者

    记住在
    ViewModel
    onCleared()事件中删除此观察者:

    val observer = new Observer() {
      override public void onChanged(Integer integer) {
        //Do something with "integer"
      }
    }
    


    非常好的参考示例。

    尝试了
    MediatorLiveData
    转换#map
    /
    转换#switchMap
    ?实际上我还没有返回LiveData字符串,我将返回一个MediatorLiveData并添加两个源,然后在我的片段中添加一个观察者,对吗?首先尝试
    转换
    类-似乎这是最简单的方法-如果不是,当涉及到
    MediatorLiveData
    您所说的“两个源”是什么意思?有一个来源是变化的,不是吗?看,我现在知道了,我能够通过转换使它工作。我用额外的信息更新了我的问题。Fuel是我的HttpClient,Fuel.request是Fuel中的一个方法,它将FuelRouting接口转换为请求,在这里我为GET方法的返回创建一个观察者。
    liveData.observeForever(observer);
    
    override fun onCleared() {
        liveData.removeObserver(observer) 
        super.onCleared()
    }