gpt4 book ai didi

android - 如何使用应用内更新库防止内存泄漏

转载 作者:行者123 更新时间:2023-12-02 14:22:17 26 4
gpt4 key购买 nike

我想在我的应用程序中实现新的应用程序内更新库,但我注意到它在重新创建/旋转时会触发我的 Activity 中的内存泄漏。

这是我从 LeakCanary 获得的唯一细节:

LeakCanary trace

显然,如果我从应用内更新库中删除代码,尤其是 addOnSuccessListener ,我将一无所获:

appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)){
updateInfo.value = appUpdateInfo
updateAvailable.value = true
}else{
updateInfo.value = null
updateAvailable.value = false
}
}

根据this post ,我首先使用了一些LiveData,但是问题是一样的,所以我使用了一个完整的类来处理回调,用LiveData:

我的服务类别:

class AppUpdateService {

val updateAvailable: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateDownloaded: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateInfo: MutableLiveData<AppUpdateInfo> by lazy { MutableLiveData<AppUpdateInfo>() }

fun checkForUpdate(appUpdateManager: AppUpdateManager){
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)){
updateInfo.value = appUpdateInfo
updateAvailable.value = true
}else{
updateInfo.value = null
updateAvailable.value = false
}
}
}

fun checkUpdateOnResume(appUpdateManager: AppUpdateManager){
appUpdateManager.appUpdateInfo.addOnSuccessListener {
updateDownloaded.value = (it.installStatus() == InstallStatus.DOWNLOADED)
}
}
}

我的 Activity 已简化:

class MainActivity : BaseActivity(), InstallStateUpdatedListener {

override fun contentViewID(): Int { return R.layout.activity_main }

private val UPDATE_REQUEST_CODE = 8000

private lateinit var appUpdateManager : AppUpdateManager

private val appUpdateService = AppUpdateService()

override fun onStateUpdate(state: InstallState?) {
if(state?.installStatus() == InstallStatus.DOWNLOADED){ notifyUser() }
}

// Called in the onCreate()
override fun setupView(){
appUpdateManager = AppUpdateManagerFactory.create(this)
appUpdateManager.registerListener(this)
setupAppUpdateServiceObservers()
// Check for Update
appUpdateService.checkForUpdate(appUpdateManager)
}

private fun setupAppUpdateServiceObservers(){
appUpdateService.updateAvailable.observe(this, Observer {
if (it)
requestUpdate(appUpdateService.updateInfo.value)
})

appUpdateService.updateDownloaded.observe(this, Observer {
if (it)
notifyUser()
})
}

private fun requestUpdate(appUpdateInfo: AppUpdateInfo?){
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.FLEXIBLE, this, UPDATE_REQUEST_CODE)
}

private fun notifyUser(){
showSnackbar(getString(R.string.updated_downloaded), getString(R.string.restart)) {
appUpdateManager.completeUpdate()
appUpdateManager.unregisterListener(this)
}
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == UPDATE_REQUEST_CODE) {
if (resultCode != RESULT_OK) {
Timber.d("Update flow failed! Result code: $resultCode")
}
}
}

override fun onDestroy() {
appUpdateManager.unregisterListener(this)
super.onDestroy()
}

override fun onResume() {
super.onResume()
appUpdateService.checkUpdateOnResume(appUpdateManager)
}

}

我真的不明白如何避免内存泄漏,因为 appUpdateManager 必须在 Activity 的上下文中创建,并且它看起来是导致回调内存泄漏的原因。

是否有人已经实现了它而没有出现此问题?

最佳答案

使用对上下文的弱引用可能会解决您的内存泄漏问题。在您的 Activity 中写入以下内容:

WeakReference<Context> contextWeakReference = new WeakReference<Context>(this);

Context context = contextWeakReference.get();
if (context != null) {
// Register using context here
}

有很多关于弱引用、垃圾收集和内存泄漏的好文章,可以阅读有关该主题的更多信息。

此外,不保证调用 onDestroy()。当您启动另一个 Activity 时,将调用 onPause() 和 onStop() 方法,而不是 onDestroy()。

当您点击后退按钮或调用 finish() 方法时,onDestroy() 会调用。因此,在 onPause() 或 onStop() 中取消注册 Listener。如果在onDestroy()方法中取消注册,可能会导致内存泄漏。

另一个想法是,由于 AppUpdateService 类不是 ViewModel 的子类,因此它不具有生命周期感知能力。我不确定,但是,您可能需要在 Activity 的 onstop/onDestroy 中删除观察者并将它们添加到 onResume 中。 (观察者对 LifecycleOwner 有很强的引用,这里是 Activity )为此,您需要定义观察者以便以后能够删除它们。类似于:

MutableLiveData<Boolean> someData = new MutableLiveData<>;

然后在 onResume 中:

someData = appUpdateService.updateAvailable;
someData.observe()

在 onStop 中:

someData.removeObservers()

这只是一个猜测,但是,我希望它能有所帮助。

关于android - 如何使用应用内更新库防止内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58433545/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com