architecture-components-samples icon indicating copy to clipboard operation
architecture-components-samples copied to clipboard

Passs parameter WeakReference<View> to method of ViewModel ?

Open bembem1011 opened this issue 5 years ago • 1 comments

Our teams are debating whether we should pass parameter WeakReference<View> to method of ViewModel or not. I see in the google's document said

Note: Since the ViewModel outlives specific activity and fragment instantiations, it should never reference a View, or any class that may hold a reference to the activity context. If the ViewModel needs the Application context (for example, to find a system service), it can extend the AndroidViewModel class and have a constructor that receives the Application in the constructor (since Application class extends Context).

How about if we use WeakReference<View> to pass view to viewmodel ? WeakRef can prevent the leak memory can occur, however some members said it will make reading/maintain code difficultly. Some guys suggest use interface ViewInf and View will implement to ViewInf and method use in viewmodel will be like that.

fun methodA(viewInf: WeakReference<ViewInf>)() { doSomeBackgroundThread(viewInf) }

We want to use this view to draw on bitmap and use bitmap to save into memcache.

@yigit

bembem1011 avatar May 31 '19 02:05 bembem1011

weak reference is use navigation from ViewModel to Activity/Fragment through Callback, i thick you team using RxJava , you can create Data class Output in ViewModel to handling navigator and Input to handling filed form Activity/Fragment and fun transform to handling Input and Output

_ 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)
}_

nguyenvanminhfptpoly avatar Feb 06 '20 07:02 nguyenvanminhfptpoly