Fixed memory leak on API level 24.

*  When the application goes in the background from `ZimHostFragment`, `KiwixReaderFragment/ZimHostFragment` without starting the Service then the `ReadAloudService`, and `HotspotService` variables are not used and GC try to clear those objects but we are not clearing those objects, that's why memory leak is happening. So now we have free those objects if they are not in use.
This commit is contained in:
MohitMali 2023-10-16 12:48:56 +05:30 committed by Kelson
parent 3432b32431
commit c3049a6a59
2 changed files with 33 additions and 6 deletions

View File

@ -333,6 +333,7 @@ abstract class CoreReaderFragment :
private var readAloudService: ReadAloudService? = null private var readAloudService: ReadAloudService? = null
private var navigationHistoryList: MutableList<NavigationHistoryListItem> = ArrayList() private var navigationHistoryList: MutableList<NavigationHistoryListItem> = ArrayList()
private var isReadSelection = false private var isReadSelection = false
private var isReadAloudServiceRunning = false
private var storagePermissionForNotesLauncher: ActivityResultLauncher<String>? = private var storagePermissionForNotesLauncher: ActivityResultLauncher<String>? =
registerForActivityResult( registerForActivityResult(
@ -1047,8 +1048,7 @@ abstract class CoreReaderFragment :
} catch (ignore: IllegalArgumentException) { } catch (ignore: IllegalArgumentException) {
// to handle if service is already unbounded // to handle if service is already unbounded
} }
readAloudService?.registerCallBack(null) unRegisterReadAloudService()
readAloudService = null
storagePermissionForNotesLauncher?.unregister() storagePermissionForNotesLauncher?.unregister()
storagePermissionForNotesLauncher = null storagePermissionForNotesLauncher = null
} }
@ -2074,9 +2074,17 @@ abstract class CoreReaderFragment :
private fun unbindService() { private fun unbindService() {
readAloudService?.let { readAloudService?.let {
requireActivity().unbindService(serviceConnection) requireActivity().unbindService(serviceConnection)
if (!isReadAloudServiceRunning) {
unRegisterReadAloudService()
}
} }
} }
private fun unRegisterReadAloudService() {
readAloudService?.registerCallBack(null)
readAloudService = null
}
private fun createReadAloudIntent(action: String, isPauseTTS: Boolean): Intent = private fun createReadAloudIntent(action: String, isPauseTTS: Boolean): Intent =
Intent(requireActivity(), ReadAloudService::class.java).apply { Intent(requireActivity(), ReadAloudService::class.java).apply {
setAction(action) setAction(action)
@ -2086,7 +2094,11 @@ abstract class CoreReaderFragment :
} }
private fun setActionAndStartTTSService(action: String, isPauseTTS: Boolean = false) { private fun setActionAndStartTTSService(action: String, isPauseTTS: Boolean = false) {
requireActivity().startService(createReadAloudIntent(action, isPauseTTS)) requireActivity().startService(
createReadAloudIntent(action, isPauseTTS)
).also {
isReadAloudServiceRunning = action == ACTION_PAUSE_OR_RESUME_TTS
}
} }
protected abstract fun restoreViewStateOnValidJSON( protected abstract fun restoreViewStateOnValidJSON(

View File

@ -94,6 +94,7 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
private lateinit var serviceConnection: ServiceConnection private lateinit var serviceConnection: ServiceConnection
private var dialog: Dialog? = null private var dialog: Dialog? = null
private var activityZimHostBinding: ActivityZimHostBinding? = null private var activityZimHostBinding: ActivityZimHostBinding? = null
private var isHotspotServiceRunning = false
override val fragmentTitle: String? by lazy { override val fragmentTitle: String? by lazy {
getString(R.string.menu_wifi_hotspot) getString(R.string.menu_wifi_hotspot)
} }
@ -304,7 +305,11 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
} }
private fun stopServer() { private fun stopServer() {
requireActivity().startService(createHotspotIntent(ACTION_STOP_SERVER)) requireActivity().startService(
createHotspotIntent(ACTION_STOP_SERVER)
).also {
isHotspotServiceRunning = false
}
} }
private fun select(bookOnDisk: BooksOnDiskListItem.BookOnDisk) { private fun select(bookOnDisk: BooksOnDiskListItem.BookOnDisk) {
@ -341,6 +346,9 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
private fun unbindService() { private fun unbindService() {
hotspotService?.let { hotspotService?.let {
requireActivity().unbindService(serviceConnection) requireActivity().unbindService(serviceConnection)
if (!isHotspotServiceRunning) {
unRegisterHotspotService()
}
} }
} }
@ -406,11 +414,16 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
activityZimHostBinding?.recyclerViewZimHost?.adapter = null activityZimHostBinding?.recyclerViewZimHost?.adapter = null
hotspotService?.registerCallBack(null) unRegisterHotspotService()
presenter.detachView() presenter.detachView()
activityZimHostBinding = null activityZimHostBinding = null
} }
private fun unRegisterHotspotService() {
hotspotService?.registerCallBack(null)
hotspotService = null
}
// Advice user to turn on hotspot manually for API<26 // Advice user to turn on hotspot manually for API<26
private fun startHotspotManuallyDialog() { private fun startHotspotManuallyDialog() {
@ -495,7 +508,9 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra( createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra(
SELECTED_ZIM_PATHS_KEY, selectedBooksPath SELECTED_ZIM_PATHS_KEY, selectedBooksPath
).putExtra(RESTART_SERVER, restartServer) ).putExtra(RESTART_SERVER, restartServer)
) ).also {
isHotspotServiceRunning = true
}
} }
override fun onIpAddressValid() { override fun onIpAddressValid() {