如何使用 In-App Update Library 防止内存泄漏
How to prevent memory leak with In-App Update Library
我想在我的应用程序中实施新的应用程序内更新库,但我注意到它在我的 activity 中触发了内存泄漏,当它是 recreated/rotated.
这是我从 LeakCanary 获得的唯一细节:
显然,如果我从应用内更新库中删除代码,尤其是 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,但问题是一样的,所以我使用了完整的class来处理回调,LiveData :
我的服务class:
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)
}
}
我真的不明白如何避免内存泄漏,因为必须使用 activity 的上下文创建 appUpdateManager,它看起来是导致回调内存泄漏的原因.
是否有人已经在没有遇到这个问题的情况下实施了它?
使用对上下文的弱引用可能会解决您的内存泄漏问题。在你的 activity 中写下:
WeakReference<Context> contextWeakReference = new WeakReference<Context>(this);
Context context = contextWeakReference.get();
if (context != null) {
// Register using context here
}
有很多关于弱引用、垃圾收集和内存泄漏的好文章,可以阅读更多关于该主题的文章。
此外,不保证会调用 onDestroy()。当您启动另一个 Activity 时,将调用 onPause() 和 onStop() 方法而不是 onDestroy()。
onDestroy() 在您点击返回按钮或调用 finish() 方法时调用。因此,在 onPause() 或 onStop() 中注销 Listener。如果您在 onDestroy() 方法中取消注册,可能会导致内存泄漏。
另一个想法是,由于 AppUpdateService class 不是 ViewModel 的子class,因此它不了解生命周期。我不确定,但是,您可能需要删除 activity 的 onstop/onDestroy 中的观察者并将它们添加到 onResume 中。 (观察者对 LifecycleOwner 有很强的引用,这里是活动)为此,您需要定义观察者以便以后能够删除它们。类似于:
MutableLiveData<Boolean> someData = new MutableLiveData<>;
然后在 onResume 中:
someData = appUpdateService.updateAvailable;
someData.observe()
并在 onStop 中:
someData.removeObservers()
这只是一个猜测,但我希望它能有所帮助。
感谢@Sina Farahzadi,我搜索并尝试了很多东西,发现问题出在 appUpdateManager.appUdateInfo
调用 Task 对象。
我发现解决内存泄漏的方法是使用applicationContext而不是activity的上下文。我不确定这是最好的解决方案,但这是我目前找到的解决方案。我已经在我的服务 class 中导出了所有内容,所以这是我的代码:
AppUpdateService.kt :
class AppUpdateService : InstallStateUpdatedListener {
val updateAvailable: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateDownloaded: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val notifyUser: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateInfo: MutableLiveData<AppUpdateInfo> by lazy { MutableLiveData<AppUpdateInfo>() }
private var appUpdateManager : AppUpdateManager? = null
private var appUpdateInfoTask: Task<AppUpdateInfo>? = null
override fun onStateUpdate(state: InstallState?) {
notifyUser.value = (state?.installStatus() == InstallStatus.DOWNLOADED)
}
fun setupAppUpdateManager(context: Context){
appUpdateManager = AppUpdateManagerFactory.create(context)
appUpdateManager?.registerListener(this)
checkForUpdate()
}
fun onStopCalled(){
appUpdateManager?.unregisterListener(this)
appUpdateInfoTask = null
appUpdateManager = null
}
fun checkForUpdate(){
appUpdateInfoTask = appUpdateManager?.appUpdateInfo
appUpdateInfoTask?.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 startUpdate(activity: Activity, code: Int){
appUpdateManager?.startUpdateFlowForResult(updateInfo.value, AppUpdateType.FLEXIBLE, activity, code)
}
fun updateComplete(){
appUpdateManager?.completeUpdate()
appUpdateManager?.unregisterListener(this)
}
fun checkUpdateOnResume(){
appUpdateManager?.appUpdateInfo?.addOnSuccessListener {
updateDownloaded.value = (it.installStatus() == InstallStatus.DOWNLOADED)
}
}
}
MainActivity 简化:
class MainActivity : BaseActivity(){
override fun contentViewID(): Int { return R.layout.activity_main }
private val UPDATE_REQUEST_CODE = 8000
private var appUpdateService: AppUpdateService? = AppUpdateService()
/**
* Setup the view of the activity (navigation and menus)
*/
override fun setupView(){
val contextWeakReference = WeakReference<Context>(applicationContext)
contextWeakReference.get()?.let {weakContext ->
appUpdateService?.setupAppUpdateManager(weakContext)
}
}
private fun setupAppUpdateServiceObservers(){
appUpdateService?.updateAvailable?.observe(this, Observer {
if (it)
requestUpdate()
})
appUpdateService?.updateDownloaded?.observe(this, Observer {
if (it)
notifyUser()
})
appUpdateService?.notifyUser?.observe(this, Observer {
if (it)
notifyUser()
})
}
private fun removeAppUpdateServiceObservers(){
appUpdateService?.updateAvailable?.removeObservers(this)
appUpdateService?.updateDownloaded?.removeObservers(this)
appUpdateService?.notifyUser?.removeObservers(this)
}
private fun requestUpdate(){
appUpdateService?.startUpdate(this, UPDATE_REQUEST_CODE)
}
private fun notifyUser(){
showSnackbar(getString(R.string.updated_downloaded), getString(R.string.restart)) {
appUpdateService?.updateComplete()
}
}
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 onStop() {
appUpdateService?.onStopCalled()
removeAppUpdateServiceObservers()
appUpdateService = null
super.onStop()
}
override fun onResume() {
super.onResume()
setupAppUpdateServiceObservers()
appUpdateService?.checkUpdateOnResume()
}
}
目前,我会保持这种状态,并继续寻找另一种方法来实现它。
如果有人有更好的方法,请告诉我。
使用这个助手class:
class GoogleUpdater(activity: FragmentActivity) : LifecycleObserver {
private val appUpdateManager = AppUpdateManagerFactory.create(activity)
private var installStateUpdatedListener: InstallStateUpdatedListener? = null
private var wra = WeakReference(activity)
private val activity get() = wra.get()
init {
activity.lifecycle.addObserver(this)
}
fun checkUpdate() {
fun showCompleteUpdateDialog() {
activity?.let { activity ->
if (!activity.isFinishing)
AlertDialog.Builder(activity)
.setTitle(R.string.notification)
.setMessage(R.string.restart_to_complete_update)
.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_notification)
?.apply {
mutate()
alpha = 127
})
.setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> appUpdateManager.completeUpdate() }
.setNegativeButton(R.string.no, null)
.create()
.apply { setCanceledOnTouchOutside(false) }
.show()
}
}
installStateUpdatedListener = object : InstallStateUpdatedListener {
override fun onStateUpdate(state: InstallState) {
if (state.installStatus() == InstallStatus.DOWNLOADED)
showCompleteUpdateDialog()
else if (state.installStatus() == InstallStatus.INSTALLED)
appUpdateManager.unregisterListener(this)
}
}.also { appUpdateManager.registerListener(it) }
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
val clientVersionStalenessDays = appUpdateInfo.clientVersionStalenessDays()
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
&& clientVersionStalenessDays != null
&& clientVersionStalenessDays >= DAYS_FOR_FLEXIBLE_UPDATE) {
try {
activity?.let { activity ->
if (!activity.isFinishing)
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
activity,
REQUEST_CODE_APP_UPDATE)
}
} catch (e: SendIntentException) {
FirebaseCrashlytics.getInstance().recordException(e)
}
} else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED)
showCompleteUpdateDialog()
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private fun onStop() {
installStateUpdatedListener?.let { appUpdateManager.unregisterListener(it) }
}
companion object {
const val REQUEST_CODE_APP_UPDATE = 11
const val DAYS_FOR_FLEXIBLE_UPDATE = 1
}
}
在Activity中:
GoogleUpdater(this).apply { checkUpdate() }
我想在我的应用程序中实施新的应用程序内更新库,但我注意到它在我的 activity 中触发了内存泄漏,当它是 recreated/rotated.
这是我从 LeakCanary 获得的唯一细节:
显然,如果我从应用内更新库中删除代码,尤其是 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,但问题是一样的,所以我使用了完整的class来处理回调,LiveData :
我的服务class:
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)
}
}
我真的不明白如何避免内存泄漏,因为必须使用 activity 的上下文创建 appUpdateManager,它看起来是导致回调内存泄漏的原因.
是否有人已经在没有遇到这个问题的情况下实施了它?
使用对上下文的弱引用可能会解决您的内存泄漏问题。在你的 activity 中写下:
WeakReference<Context> contextWeakReference = new WeakReference<Context>(this);
Context context = contextWeakReference.get();
if (context != null) {
// Register using context here
}
有很多关于弱引用、垃圾收集和内存泄漏的好文章,可以阅读更多关于该主题的文章。
此外,不保证会调用 onDestroy()。当您启动另一个 Activity 时,将调用 onPause() 和 onStop() 方法而不是 onDestroy()。
onDestroy() 在您点击返回按钮或调用 finish() 方法时调用。因此,在 onPause() 或 onStop() 中注销 Listener。如果您在 onDestroy() 方法中取消注册,可能会导致内存泄漏。
另一个想法是,由于 AppUpdateService class 不是 ViewModel 的子class,因此它不了解生命周期。我不确定,但是,您可能需要删除 activity 的 onstop/onDestroy 中的观察者并将它们添加到 onResume 中。 (观察者对 LifecycleOwner 有很强的引用,这里是活动)为此,您需要定义观察者以便以后能够删除它们。类似于:
MutableLiveData<Boolean> someData = new MutableLiveData<>;
然后在 onResume 中:
someData = appUpdateService.updateAvailable;
someData.observe()
并在 onStop 中:
someData.removeObservers()
这只是一个猜测,但我希望它能有所帮助。
感谢@Sina Farahzadi,我搜索并尝试了很多东西,发现问题出在 appUpdateManager.appUdateInfo
调用 Task 对象。
我发现解决内存泄漏的方法是使用applicationContext而不是activity的上下文。我不确定这是最好的解决方案,但这是我目前找到的解决方案。我已经在我的服务 class 中导出了所有内容,所以这是我的代码:
AppUpdateService.kt :
class AppUpdateService : InstallStateUpdatedListener {
val updateAvailable: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateDownloaded: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val notifyUser: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
val updateInfo: MutableLiveData<AppUpdateInfo> by lazy { MutableLiveData<AppUpdateInfo>() }
private var appUpdateManager : AppUpdateManager? = null
private var appUpdateInfoTask: Task<AppUpdateInfo>? = null
override fun onStateUpdate(state: InstallState?) {
notifyUser.value = (state?.installStatus() == InstallStatus.DOWNLOADED)
}
fun setupAppUpdateManager(context: Context){
appUpdateManager = AppUpdateManagerFactory.create(context)
appUpdateManager?.registerListener(this)
checkForUpdate()
}
fun onStopCalled(){
appUpdateManager?.unregisterListener(this)
appUpdateInfoTask = null
appUpdateManager = null
}
fun checkForUpdate(){
appUpdateInfoTask = appUpdateManager?.appUpdateInfo
appUpdateInfoTask?.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 startUpdate(activity: Activity, code: Int){
appUpdateManager?.startUpdateFlowForResult(updateInfo.value, AppUpdateType.FLEXIBLE, activity, code)
}
fun updateComplete(){
appUpdateManager?.completeUpdate()
appUpdateManager?.unregisterListener(this)
}
fun checkUpdateOnResume(){
appUpdateManager?.appUpdateInfo?.addOnSuccessListener {
updateDownloaded.value = (it.installStatus() == InstallStatus.DOWNLOADED)
}
}
}
MainActivity 简化:
class MainActivity : BaseActivity(){
override fun contentViewID(): Int { return R.layout.activity_main }
private val UPDATE_REQUEST_CODE = 8000
private var appUpdateService: AppUpdateService? = AppUpdateService()
/**
* Setup the view of the activity (navigation and menus)
*/
override fun setupView(){
val contextWeakReference = WeakReference<Context>(applicationContext)
contextWeakReference.get()?.let {weakContext ->
appUpdateService?.setupAppUpdateManager(weakContext)
}
}
private fun setupAppUpdateServiceObservers(){
appUpdateService?.updateAvailable?.observe(this, Observer {
if (it)
requestUpdate()
})
appUpdateService?.updateDownloaded?.observe(this, Observer {
if (it)
notifyUser()
})
appUpdateService?.notifyUser?.observe(this, Observer {
if (it)
notifyUser()
})
}
private fun removeAppUpdateServiceObservers(){
appUpdateService?.updateAvailable?.removeObservers(this)
appUpdateService?.updateDownloaded?.removeObservers(this)
appUpdateService?.notifyUser?.removeObservers(this)
}
private fun requestUpdate(){
appUpdateService?.startUpdate(this, UPDATE_REQUEST_CODE)
}
private fun notifyUser(){
showSnackbar(getString(R.string.updated_downloaded), getString(R.string.restart)) {
appUpdateService?.updateComplete()
}
}
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 onStop() {
appUpdateService?.onStopCalled()
removeAppUpdateServiceObservers()
appUpdateService = null
super.onStop()
}
override fun onResume() {
super.onResume()
setupAppUpdateServiceObservers()
appUpdateService?.checkUpdateOnResume()
}
}
目前,我会保持这种状态,并继续寻找另一种方法来实现它。 如果有人有更好的方法,请告诉我。
使用这个助手class:
class GoogleUpdater(activity: FragmentActivity) : LifecycleObserver {
private val appUpdateManager = AppUpdateManagerFactory.create(activity)
private var installStateUpdatedListener: InstallStateUpdatedListener? = null
private var wra = WeakReference(activity)
private val activity get() = wra.get()
init {
activity.lifecycle.addObserver(this)
}
fun checkUpdate() {
fun showCompleteUpdateDialog() {
activity?.let { activity ->
if (!activity.isFinishing)
AlertDialog.Builder(activity)
.setTitle(R.string.notification)
.setMessage(R.string.restart_to_complete_update)
.setIcon(ContextCompat.getDrawable(activity, R.drawable.ic_notification)
?.apply {
mutate()
alpha = 127
})
.setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> appUpdateManager.completeUpdate() }
.setNegativeButton(R.string.no, null)
.create()
.apply { setCanceledOnTouchOutside(false) }
.show()
}
}
installStateUpdatedListener = object : InstallStateUpdatedListener {
override fun onStateUpdate(state: InstallState) {
if (state.installStatus() == InstallStatus.DOWNLOADED)
showCompleteUpdateDialog()
else if (state.installStatus() == InstallStatus.INSTALLED)
appUpdateManager.unregisterListener(this)
}
}.also { appUpdateManager.registerListener(it) }
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
val clientVersionStalenessDays = appUpdateInfo.clientVersionStalenessDays()
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
&& clientVersionStalenessDays != null
&& clientVersionStalenessDays >= DAYS_FOR_FLEXIBLE_UPDATE) {
try {
activity?.let { activity ->
if (!activity.isFinishing)
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
activity,
REQUEST_CODE_APP_UPDATE)
}
} catch (e: SendIntentException) {
FirebaseCrashlytics.getInstance().recordException(e)
}
} else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED)
showCompleteUpdateDialog()
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private fun onStop() {
installStateUpdatedListener?.let { appUpdateManager.unregisterListener(it) }
}
companion object {
const val REQUEST_CODE_APP_UPDATE = 11
const val DAYS_FOR_FLEXIBLE_UPDATE = 1
}
}
在Activity中:
GoogleUpdater(this).apply { checkUpdate() }