android: Use suspend function for creating dynamic shortcuts
If the coil loader ever got stuck when creating a dynamic shortcut icon, the app would freeze. This would happen most notably when booting nca format games. This pushes that process to a separate coroutine that can be cancelled by the main activity's lifecycle.
This commit is contained in:
parent
247d66a680
commit
4d0b7f8496
|
@ -22,12 +22,16 @@ import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
@ -92,28 +96,34 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
data = Uri.parse(holder.game.path)
|
data = Uri.parse(holder.game.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
val layerDrawable = ResourcesCompat.getDrawable(
|
activity.lifecycleScope.launch {
|
||||||
YuzuApplication.appContext.resources,
|
withContext(Dispatchers.IO) {
|
||||||
R.drawable.shortcut,
|
val layerDrawable = ResourcesCompat.getDrawable(
|
||||||
null
|
YuzuApplication.appContext.resources,
|
||||||
) as LayerDrawable
|
R.drawable.shortcut,
|
||||||
layerDrawable.setDrawableByLayerId(
|
null
|
||||||
R.id.shortcut_foreground,
|
) as LayerDrawable
|
||||||
GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources)
|
layerDrawable.setDrawableByLayerId(
|
||||||
)
|
R.id.shortcut_foreground,
|
||||||
val inset = YuzuApplication.appContext.resources
|
GameIconUtils.getGameIcon(activity, holder.game)
|
||||||
.getDimensionPixelSize(R.dimen.icon_inset)
|
.toDrawable(YuzuApplication.appContext.resources)
|
||||||
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
|
|
||||||
val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
|
|
||||||
.setShortLabel(holder.game.title)
|
|
||||||
.setIcon(
|
|
||||||
IconCompat.createWithAdaptiveBitmap(
|
|
||||||
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
|
|
||||||
)
|
)
|
||||||
)
|
val inset = YuzuApplication.appContext.resources
|
||||||
.setIntent(openIntent)
|
.getDimensionPixelSize(R.dimen.icon_inset)
|
||||||
.build()
|
layerDrawable.setLayerInset(1, inset, inset, inset, inset)
|
||||||
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
val shortcut =
|
||||||
|
ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
|
||||||
|
.setShortLabel(holder.game.title)
|
||||||
|
.setIcon(
|
||||||
|
IconCompat.createWithAdaptiveBitmap(
|
||||||
|
layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setIntent(openIntent)
|
||||||
|
.build()
|
||||||
|
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
|
val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
|
||||||
view.findNavController().navigate(action)
|
view.findNavController().navigate(action)
|
||||||
|
|
|
@ -8,9 +8,9 @@ import android.graphics.BitmapFactory
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import coil.decode.DataSource
|
import coil.decode.DataSource
|
||||||
import coil.executeBlocking
|
|
||||||
import coil.fetch.DrawableResult
|
import coil.fetch.DrawableResult
|
||||||
import coil.fetch.FetchResult
|
import coil.fetch.FetchResult
|
||||||
import coil.fetch.Fetcher
|
import coil.fetch.Fetcher
|
||||||
|
@ -76,12 +76,13 @@ object GameIconUtils {
|
||||||
imageLoader.enqueue(request)
|
imageLoader.enqueue(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGameIcon(game: Game): Bitmap {
|
suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap {
|
||||||
val request = ImageRequest.Builder(YuzuApplication.appContext)
|
val request = ImageRequest.Builder(YuzuApplication.appContext)
|
||||||
.data(game)
|
.data(game)
|
||||||
|
.lifecycle(lifecycleOwner)
|
||||||
.error(R.drawable.default_icon)
|
.error(R.drawable.default_icon)
|
||||||
.build()
|
.build()
|
||||||
return imageLoader.executeBlocking(request)
|
return imageLoader.execute(request)
|
||||||
.drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
|
.drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue