Reputation: 2325
I have read the articals
This Field leaks context object
This field leaks a context object
The Code private var mService: RecordService? = null
show a warning "This field leaks a context object" ? why?
I think that HomeViewModel
object will be destroyed after Activity
object destroyed, and the mService
will be released too, why does Android Studio display "This field leaks a context object" ?
class HomeViewModel(private val mApplication: Application, private val mDBVoiceRepository: DBVoiceRepository) : AndroidViewModel(mApplication) {
private var mService: RecordService? = null
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, iBinder: IBinder) {
val binder = iBinder as RecordService.MyBinder
mService = binder.service
}
}
fun bindService() {
Intent(mApplication , RecordService::class.java).also { intent ->
mApplication.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
}
fun unbindService() {
Intent(mApplication, RecordService::class.java).also { intent ->
mApplication.unbindService(serviceConnection)
mService?.stopForeground(true)
mService?.stopSelf()
}
}
...
}
class RecordService : Service() {
override fun onBind(intent: Intent): IBinder {
return MyBinder()
}
inner class MyBinder : Binder() {
val service: RecordService
get() = this@RecordService
}
...
}
Added Content
To AlphaOne: Thanks!
I still get the warning "This field leaks a context object" when I use the following code, how can I do if I need call RecordService
in HomeViewModel
?
class HomeViewModel(private val mApplication: Application,
private val mDBVoiceRepository: DBVoiceRepository,
private var mService: RecordService?) :
AndroidViewModel(mApplication) {
}
And more, the following code is source code of AndroidViewModel
, it seems that Android doesn't do extra works for the class AndroidViewModel
, it seems that android prevent to display the warning information.
public class AndroidViewModel extends ViewModel {
@SuppressLint("StaticFieldLeak")
private Application mApplication;
public AndroidViewModel(@NonNull Application application) {
mApplication = application;
}
/**
* Return the application.
*/
@SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
@NonNull
public <T extends Application> T getApplication() {
return (T) mApplication;
}
}
Upvotes: 1
Views: 617
Reputation: 4528
From the Official docs:
A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.
Since the services have their own lifecycle and are managed by Operating Systems, you shouldn't keep its reference inside the ViewModel.
During configuration change, the ViewModel is preserved, so still may have reference to Service and will cause the memory leak.
Upvotes: 3