For the More Curious: Canceling Requests

In your current implementation, PhotoGalleryFragment asks its ViewModel, PhotoGalleryViewModel, to start a web request to download photo data. If the user presses the Back button quickly enough after launching your application, it is possible that the web request will continue even after the user exits the activity. This will not cause a memory leak, because FlickrFetchr does not hold references to any UI-related components, nor to the ViewModel.

However, since you are ignoring the results, allowing the request to continue will cause some minimal wasted battery, wasted CPU cycles, and possibly some wasted paid data usage if the user is on a metered network. Granted, there is no major harm in this case, since the data size you are fetching is very small.

In most production applications, you would likely let the request continue, as you do here. But rather than ignoring the result, you would cache it somewhere locally, like in a database.

Since you are not caching the results in your current implementation, you could instead cancel an in-flight request when the ViewModel is destroyed. To do so, you would stash the Call object representing an in-flight web request. Then you would cancel the web request by calling Call.cancel() on the call object(s) you stashed:

    class SomeRespositoryClass {

        private lateinit var someCall: Call<SomeResponseType>
        ...
        fun cancelRequestInFlight() {
            if (::someCall.isInitialized) {
                someCall.cancel()
            }
        }
    }

When you cancel a Call object, the corresponding Callback.onFailure(…) method will be called. You can check the value of Call.isCancelled to determine whether the failure was due to a canceled request (a value of true means the request was indeed canceled).

To hook into the ViewModel lifecycle, and more specifically to cancel calls when a ViewModel is destroyed, you override ViewModel.onCleared(). This function is called when the ViewModel is about to be destroyed (such as when the user backs out of the activity using the Back button).

    class SomeViewModel : ViewModel() {

        private val someRepository = SomeRespositoryClass()
        ...
        override fun onCleared() {
            super.onCleared()
            someRepository.cancelRequestInFlight()
        }
        ...
    }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
54.81.61.14