Skip to content
Snippets Groups Projects
Commit b2490c61 authored by Hugh Daschbach's avatar Hugh Daschbach
Browse files

Fix landscape view induced MainActivity leak.

With landscape view enabled (e.g. e06b2c7d) in the app and auto
rotation enabled on the phone, switching between portrait and
landscape orientations leaks instances of MainActivity.  This prevents
garbage collection of not just the MainActivity object, but fragments
and other objects referenced by the Activity.

This is caused by repositories, the AppContext instance, the player
service, and authentication code maintaining a reference to the
context which with they are initialized.  So rather than initialize
these with an Activity context, pass them the Application context.

Activities are torn down and rebuilt on screen rotation.  The
Application context is not.

To enable instantiation of the FavoritedRepository with the
Application context, delay that repository’s initialization until
first use.  This ensures the Application context is fully initialized.
It is not fully initialized until the MainActivity has been fully
initialized.
parent eaf3c550
No related branches found
No related tags found
1 merge request!331Extend merge request !310
Pipeline #33403 passed
...@@ -69,7 +69,9 @@ class MainActivity : AppCompatActivity() { ...@@ -69,7 +69,9 @@ class MainActivity : AppCompatActivity() {
LOGOUT(1001) LOGOUT(1001)
} }
private val favoritedRepository = FavoritedRepository(this) private val favoritedRepository by lazy {
FavoritedRepository(applicationContext)
}
private var menu: Menu? = null private var menu: Menu? = null
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
...@@ -82,8 +84,7 @@ class MainActivity : AppCompatActivity() { ...@@ -82,8 +84,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AppContext.init(this) AppContext.init(applicationContext)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
(supportFragmentManager.findFragmentById(R.id.now_playing) as NowPlayingFragment).apply { (supportFragmentManager.findFragmentById(R.id.now_playing) as NowPlayingFragment).apply {
...@@ -141,15 +142,15 @@ class MainActivity : AppCompatActivity() { ...@@ -141,15 +142,15 @@ class MainActivity : AppCompatActivity() {
super.onResume() super.onResume()
binding.nowPlaying.getFragment<NowPlayingFragment>().apply { binding.nowPlaying.getFragment<NowPlayingFragment>().apply {
favoritedRepository.update(this@MainActivity, lifecycleScope) favoritedRepository.update(applicationContext, lifecycleScope)
startService(Intent(this@MainActivity, PlayerService::class.java)) startService(Intent(applicationContext, PlayerService::class.java))
DownloadService.start(this@MainActivity, PinService::class.java) DownloadService.start(applicationContext, PinService::class.java)
CommandBus.send(Command.RefreshService) CommandBus.send(Command.RefreshService)
lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
Userinfo.get(this@MainActivity, oAuth) Userinfo.get(applicationContext, oAuth)
} }
} }
} }
...@@ -343,7 +344,7 @@ class MainActivity : AppCompatActivity() { ...@@ -343,7 +344,7 @@ class MainActivity : AppCompatActivity() {
try { try {
Fuel Fuel
.post(mustNormalizeUrl("/api/v1/history/listenings/")) .post(mustNormalizeUrl("/api/v1/history/listenings/"))
.authorize(this@MainActivity, oAuth) .authorize(applicationContext, oAuth)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(Gson().toJson(mapOf("track" to track.id))) .body(Gson().toJson(mapOf("track" to track.id)))
.awaitStringResponse() .awaitStringResponse()
......
package audio.funkwhale.ffa.utils package audio.funkwhale.ffa.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
...@@ -23,7 +22,7 @@ object AppContext { ...@@ -23,7 +22,7 @@ object AppContext {
const val PAGE_SIZE = 50 const val PAGE_SIZE = 50
const val TRANSITION_DURATION = 300L const val TRANSITION_DURATION = 300L
fun init(context: Activity) { fun init(context: Context) {
setupNotificationChannels(context) setupNotificationChannels(context)
// CastContext.getSharedInstance(context) // CastContext.getSharedInstance(context)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment