Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context. #65

Open
ameybhandarkar opened this issue Aug 26, 2019 · 6 comments

Comments

@ameybhandarkar
Copy link
Author

ameybhandarkar commented Aug 26, 2019

I am trying to implement MVVM in my current project. I was searching for some references. I just to clear a few doubts. So you can correct me if I am wrong.

mLoginViewModel.setNavigator(this);

This line of code is actually passing on the reference of the current activity to that viewmodel. But as per documentation, Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.
So is there any alternative to this?

I am also searching for an approach of handling errors thrown by the API. I'd be glad if you can guide me through. Thanks

@clj0020
Copy link

clj0020 commented Aug 26, 2019

@ameybhandarkar the navigator is an interface between the activity and the viewmodel. That is not holding a reference to a context or really anything. There is a special kind of viewmodel called the AndroidViewModel that does hold reference to a context.

@ArthurSav
Copy link

@clj0020 It holds a reference to the object that implements the interface, in this case the activity. There are better ways to notify the UI, try using Live Data.

@nguyenvanminhfptpoly
Copy link

nguyenvanminhfptpoly commented Feb 6, 2020

@ameybhandarkar have idea for replace Weak references

in ViewModel i create
///////////////////////////////
data class Input( val name: Observable<String>, val image: Observable<ByteArray>, val triggerAdd: Observable<Unit> ) data class Output( val isAdd: Observable<Boolean> )

fun transform(input: Input): Output{
    val nameImage = BehaviorSubject.create<String>()
    val imageLibrary = BehaviorSubject.create<ByteArray>()
    val isAdd = BehaviorSubject.create<Boolean>()


    with(input){
        name.subscribe(nameImage)
        image.subscribe(imageLibrary)
        triggerAdd.subscribe {
            val name = nameImage.value ?:""
            val image = imageLibrary.value ?: byteArrayOf()
            dataManager.insert(Library(null,name,image))
                .subscribeOn(schedulerProvider.io)
                .observeOn(schedulerProvider.ui)
                .subscribe ({
                    isAdd.onNext(it)
                },{
                    Log.d("addImage",it.message)
                })
        }

    }.addTo(compositeDisposable)
    return Output(isAdd)
}

//////////////////////////////
in Activity/Fragment i create
///////////////
private fun bindViewModel(){ val output = viewModel.transform( RoomImageViewModel.Input( edImage.textChanges().map { it.toString() }, image, btnInsert.clicks().throttleFirst(300, TimeUnit.MILLISECONDS) ) ) with(output){ isAdd.subscribe { Log.d("AddImage",it.toString()) } isDelete.subscribe { Log.d("Delete",it.toString()) } } }
//////////////

@androminor
Copy link

@ameybhandarkar the navigator is an interface between the activity and the viewmodel. That is not holding a reference to a context or really anything. There is a special kind of viewmodel called the AndroidViewModel that does hold reference to an applictation context.

@androminor
Copy link

just corrected something 👍🏿

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants