瀏覽代碼

EuiccManagementFragment: prevent crashes on configuration change

This is... not supposed to happen. We made too many assumptions about
the Fragment lifecycle.
Peter Cai 1 年之前
父節點
當前提交
324dcdc563

+ 3 - 0
app-common/src/main/java/im/angry/openeuicc/ui/BaseEuiccAccessActivity.kt

@@ -9,14 +9,17 @@ import android.os.IBinder
 import androidx.appcompat.app.AppCompatActivity
 import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.service.EuiccChannelManagerService
+import kotlinx.coroutines.CompletableDeferred
 
 abstract class BaseEuiccAccessActivity : AppCompatActivity() {
+    val euiccChannelManagerLoaded = CompletableDeferred<Unit>()
     lateinit var euiccChannelManager: EuiccChannelManager
 
     private val euiccChannelManagerServiceConnection = object : ServiceConnection {
         override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
             euiccChannelManager =
                 (service!! as EuiccChannelManagerService.LocalBinder).service.euiccChannelManager
+            euiccChannelManagerLoaded.complete(Unit)
             onInit()
         }
 

+ 5 - 0
app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt

@@ -108,7 +108,10 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
             ProfileDownloadFragment.newInstance(slotId, portId)
                 .show(childFragmentManager, ProfileDownloadFragment.TAG)
         }
+    }
 
+    override fun onStart() {
+        super.onStart()
         refresh()
     }
 
@@ -151,6 +154,8 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
         swipeRefresh.isRefreshing = true
 
         lifecycleScope.launch {
+            ensureEuiccChannelManager()
+
             if (!this@EuiccManagementFragment::disableSafeguardFlow.isInitialized) {
                 disableSafeguardFlow =
                     preferenceRepository.disableSafeguardFlow.stateIn(lifecycleScope)

+ 3 - 0
app-common/src/main/java/im/angry/openeuicc/util/EuiccChannelFragmentUtils.kt

@@ -39,6 +39,9 @@ val <T> T.channel: EuiccChannel where T: Fragment, T: EuiccChannelFragmentMarker
     get() =
         euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)!!
 
+suspend fun <T> T.ensureEuiccChannelManager() where T: Fragment, T: EuiccChannelFragmentMarker =
+    (requireActivity() as BaseEuiccAccessActivity).euiccChannelManagerLoaded.await()
+
 interface EuiccProfilesChangedListener {
     fun onEuiccProfilesChanged()
 }