Remove viewmodel memory leak
This commit is contained in:
parent
4af47e8de0
commit
368808de0c
|
@ -84,6 +84,7 @@ class ExpandableAppListAdapter(
|
|||
appDownload.apply {
|
||||
setOnClickListener {
|
||||
viewModel.openInstallDialog(
|
||||
activity.supportFragmentManager,
|
||||
buttonTag,
|
||||
apps[position]
|
||||
)
|
||||
|
|
|
@ -64,7 +64,7 @@ class LinkAdapter(
|
|||
|
||||
fun bind(position: Int) {
|
||||
binding.linkBg.setOnClickListener {
|
||||
viewModel.openUrl(links[position].linkUrl)
|
||||
viewModel.openUrl(context, links[position].linkUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class SponsorAdapter(
|
|||
with(binding) {
|
||||
sponsorName.text = sponsors[position].name
|
||||
cardSponsor.setOnClickListener {
|
||||
viewModel.openUrl(sponsors[position].url)
|
||||
viewModel.openUrl(context, sponsors[position].url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.vanced.manager.core
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
|
||||
/**
|
||||
* CombinedLiveData is a helper class to combine results from two LiveData sources.
|
||||
* @param combine Function reference that will be used to combine all LiveData data.
|
||||
* @param R The type of data returned after combining all LiveData data.
|
||||
* Usage:
|
||||
* CombinedLiveData(
|
||||
* getLiveData1(),
|
||||
* getLiveData2()
|
||||
* ) { data1, data2 ->
|
||||
* // Use datas[0], datas[1], ..., datas[N] to return a value
|
||||
* }
|
||||
*/
|
||||
class CombinedLiveData<R, A, B>(
|
||||
liveDataA: LiveData<A>,
|
||||
liveDataB: LiveData<B>,
|
||||
private val combine: (a: A?, b: B?) -> R
|
||||
) : MediatorLiveData<R>() {
|
||||
|
||||
private var a: A? = null
|
||||
private var b: B? = null
|
||||
|
||||
init {
|
||||
addSource(liveDataA) {
|
||||
a = it
|
||||
value = combine(a, b)
|
||||
}
|
||||
addSource(liveDataB) {
|
||||
b = it
|
||||
value = combine(a, b)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@ import com.vanced.manager.databinding.FragmentHomeBinding
|
|||
import com.vanced.manager.ui.dialogs.AppInfoDialog
|
||||
import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder
|
||||
import com.vanced.manager.ui.viewmodels.HomeViewModel
|
||||
import com.vanced.manager.ui.viewmodels.HomeViewModelFactory
|
||||
import com.vanced.manager.utils.isFetching
|
||||
import com.vanced.manager.utils.manager
|
||||
|
||||
|
@ -37,9 +36,7 @@ class HomeFragment : BindingFragment<FragmentHomeBinding>() {
|
|||
const val REFRESH_HOME = "REFRESH_HOME"
|
||||
}
|
||||
|
||||
private val viewModel: HomeViewModel by viewModels {
|
||||
HomeViewModelFactory(requireActivity())
|
||||
}
|
||||
private val viewModel: HomeViewModel by viewModels()
|
||||
|
||||
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(requireActivity()) }
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package com.vanced.manager.ui.viewmodels
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
|
||||
import com.vanced.manager.R
|
||||
|
@ -38,12 +39,11 @@ import com.vanced.manager.utils.PackageHelper.uninstallRootApk
|
|||
import com.vanced.manager.utils.PackageHelper.vancedInstallFilesExist
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
//TODO fix leak
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
class HomeViewModel(private val activity: FragmentActivity) : ViewModel() {
|
||||
class HomeViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private val prefs = getDefaultSharedPreferences(activity)
|
||||
private val prefs = getDefaultSharedPreferences(context)
|
||||
private val variant get() = prefs.getString("vanced_variant", "nonroot")
|
||||
private val context: Context get() = getApplication()
|
||||
|
||||
val vancedModel = MutableLiveData<DataModel>()
|
||||
val vancedRootModel = MutableLiveData<RootDataModel>()
|
||||
|
@ -54,13 +54,13 @@ class HomeViewModel(private val activity: FragmentActivity) : ViewModel() {
|
|||
|
||||
fun fetchData() {
|
||||
viewModelScope.launch {
|
||||
loadJson(activity)
|
||||
loadJson(context)
|
||||
}
|
||||
}
|
||||
|
||||
private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG)
|
||||
private val microgToast = Toast.makeText(context, R.string.no_microg, Toast.LENGTH_LONG)
|
||||
|
||||
fun openUrl(url: String) {
|
||||
fun openUrl(context: Context, url: String) {
|
||||
val color: Int =
|
||||
when (url) {
|
||||
DISCORD -> R.color.Discord
|
||||
|
@ -71,82 +71,82 @@ class HomeViewModel(private val activity: FragmentActivity) : ViewModel() {
|
|||
else -> R.color.Vanced
|
||||
}
|
||||
|
||||
openUrl(url, color, activity)
|
||||
openUrl(url, color, context)
|
||||
}
|
||||
|
||||
fun launchApp(app: String, isRoot: Boolean) {
|
||||
val componentName = when (app) {
|
||||
activity.getString(R.string.vanced) -> if (isRoot) ComponentName(
|
||||
context.getString(R.string.vanced) -> if (isRoot) ComponentName(
|
||||
vancedRootPkg,
|
||||
"$vancedRootPkg.HomeActivity"
|
||||
) else ComponentName(vancedPkg, "$vancedRootPkg.HomeActivity")
|
||||
activity.getString(R.string.music) -> if (isRoot) ComponentName(
|
||||
context.getString(R.string.music) -> if (isRoot) ComponentName(
|
||||
musicRootPkg,
|
||||
"$musicRootPkg.activities.MusicActivity"
|
||||
) else ComponentName(musicPkg, "$musicRootPkg.activities.MusicActivity")
|
||||
activity.getString(R.string.microg) -> ComponentName(
|
||||
context.getString(R.string.microg) -> ComponentName(
|
||||
microgPkg,
|
||||
"org.microg.gms.ui.SettingsActivity"
|
||||
)
|
||||
else -> throw IllegalArgumentException("Can't open this app")
|
||||
}
|
||||
try {
|
||||
activity.startActivity(Intent().setComponent(componentName))
|
||||
context.startActivity(Intent().setComponent(componentName))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
log("VMHMV", e.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun openInstallDialog(buttonTag: ButtonTag?, app: String) {
|
||||
if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microgModel.value?.isAppInstalled?.value!!) {
|
||||
fun openInstallDialog(fragmentManager: FragmentManager, buttonTag: ButtonTag?, app: String) {
|
||||
if (variant == "nonroot" && app != context.getString(R.string.microg) && !microgModel.value?.isAppInstalled?.value!!) {
|
||||
microgToast.show()
|
||||
return
|
||||
}
|
||||
|
||||
if (buttonTag == ButtonTag.UPDATE) {
|
||||
when (app) {
|
||||
activity.getString(R.string.vanced) -> VancedPreferencesDialog().show(activity)
|
||||
activity.getString(R.string.music) -> MusicPreferencesDialog().show(activity)
|
||||
else -> AppDownloadDialog.newInstance(app).show(activity)
|
||||
context.getString(R.string.vanced) -> VancedPreferencesDialog().show(fragmentManager)
|
||||
context.getString(R.string.music) -> MusicPreferencesDialog().show(fragmentManager)
|
||||
else -> AppDownloadDialog.newInstance(app).show(fragmentManager)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
when (app) {
|
||||
activity.getString(R.string.vanced) -> {
|
||||
context.getString(R.string.vanced) -> {
|
||||
when (variant) {
|
||||
"nonroot" -> {
|
||||
if (vancedInstallFilesExist(activity)) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(activity)
|
||||
if (vancedInstallFilesExist(context)) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(fragmentManager)
|
||||
} else {
|
||||
VancedPreferencesDialog().show(activity)
|
||||
VancedPreferencesDialog().show(fragmentManager)
|
||||
}
|
||||
}
|
||||
"root" -> {
|
||||
VancedPreferencesDialog().show(activity)
|
||||
VancedPreferencesDialog().show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
activity.getString(R.string.music) -> {
|
||||
context.getString(R.string.music) -> {
|
||||
when (variant) {
|
||||
"nonroot" -> {
|
||||
if (musicApkExists(activity)) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(activity)
|
||||
if (musicApkExists(context)) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(fragmentManager)
|
||||
} else {
|
||||
MusicPreferencesDialog().show(activity)
|
||||
MusicPreferencesDialog().show(fragmentManager)
|
||||
}
|
||||
}
|
||||
"root" -> {
|
||||
MusicPreferencesDialog().show(activity)
|
||||
MusicPreferencesDialog().show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
activity.getString(R.string.microg) -> {
|
||||
if (apkExist(activity, "microg.apk")) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(activity)
|
||||
context.getString(R.string.microg) -> {
|
||||
if (apkExist(context, "microg.apk")) {
|
||||
InstallationFilesDetectedDialog.newInstance(app).show(fragmentManager)
|
||||
} else {
|
||||
AppDownloadDialog.newInstance(app).show(activity)
|
||||
AppDownloadDialog.newInstance(app).show(fragmentManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,32 +155,30 @@ class HomeViewModel(private val activity: FragmentActivity) : ViewModel() {
|
|||
|
||||
fun uninstallPackage(pkg: String) {
|
||||
if (variant == "root" && uninstallRootApk(pkg)) {
|
||||
viewModelScope.launch { loadJson(activity) }
|
||||
viewModelScope.launch { loadJson(context) }
|
||||
} else {
|
||||
uninstallApk(pkg, activity)
|
||||
uninstallApk(pkg, context)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
with(activity) {
|
||||
with(context) {
|
||||
if (variant == "root") {
|
||||
vancedRootModel.value = RootDataModel(
|
||||
vanced,
|
||||
this,
|
||||
this,
|
||||
vancedRootPkg,
|
||||
this.getString(R.string.vanced),
|
||||
activity.getString(R.string.description_vanced),
|
||||
this.getString(R.string.description_vanced),
|
||||
R.drawable.ic_vanced,
|
||||
"vanced"
|
||||
)
|
||||
musicRootModel.value = RootDataModel(
|
||||
music,
|
||||
this,
|
||||
this,
|
||||
musicRootPkg,
|
||||
this.getString(R.string.music),
|
||||
activity.getString(R.string.description_vanced_music),
|
||||
this.getString(R.string.description_vanced_music),
|
||||
R.drawable.ic_music,
|
||||
"music"
|
||||
)
|
||||
|
@ -188,35 +186,31 @@ class HomeViewModel(private val activity: FragmentActivity) : ViewModel() {
|
|||
vancedModel.value = DataModel(
|
||||
vanced,
|
||||
this,
|
||||
this,
|
||||
vancedPkg,
|
||||
this.getString(R.string.vanced),
|
||||
activity.getString(R.string.description_vanced),
|
||||
this.getString(R.string.description_vanced),
|
||||
R.drawable.ic_vanced
|
||||
)
|
||||
musicModel.value = DataModel(
|
||||
music,
|
||||
this,
|
||||
this,
|
||||
musicPkg,
|
||||
this.getString(R.string.music),
|
||||
activity.getString(R.string.description_vanced_music),
|
||||
this.getString(R.string.description_vanced_music),
|
||||
R.drawable.ic_music
|
||||
)
|
||||
microgModel.value = DataModel(
|
||||
microg,
|
||||
this,
|
||||
this,
|
||||
microgPkg,
|
||||
this.getString(R.string.microg),
|
||||
activity.getString(R.string.description_microg),
|
||||
this.getString(R.string.description_microg),
|
||||
R.drawable.ic_microg
|
||||
)
|
||||
}
|
||||
managerModel.value = DataModel(
|
||||
manager,
|
||||
this,
|
||||
this,
|
||||
managerPkg,
|
||||
this.getString(R.string.app_name),
|
||||
"Just manager meh",
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package com.vanced.manager.ui.viewmodels
|
||||
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
||||
class HomeViewModelFactory(private val activity: FragmentActivity) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return HomeViewModel(activity) as T
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.widget.RadioGroup
|
|||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
|
@ -22,14 +23,18 @@ val RadioGroup.checkedButtonTag: String?
|
|||
checkedRadioButtonId
|
||||
)?.tag?.toString()
|
||||
|
||||
fun DialogFragment.show(activity: FragmentActivity) {
|
||||
fun DialogFragment.show(fragmentManager: FragmentManager) {
|
||||
try {
|
||||
show(activity.supportFragmentManager, "")
|
||||
show(fragmentManager, "")
|
||||
} catch (e: Exception) {
|
||||
log("VMUI", e.stackTraceToString())
|
||||
}
|
||||
}
|
||||
|
||||
fun DialogFragment.show(activity: FragmentActivity) {
|
||||
show(activity.supportFragmentManager)
|
||||
}
|
||||
|
||||
fun List<String>.convertToAppVersions(): List<String> = listOf("latest") + reversed()
|
||||
|
||||
fun String.formatVersion(context: Context): String =
|
||||
|
|
Loading…
Reference in New Issue