3

假设我的 Android 应用程序中有一个自定义应用程序,它在启动时异步进行网络调用。然后我有一个主要活动,需要在启动时网络调用的结果。我可以通过等待应用启动的Splash活动来处理这个问题。但是当进程重新创建时,我们直接进入Main活动,它期望网络调用的结果在那里,然后它崩溃了。

有关示例,请参见下面的代码。

处理这个问题的最佳方法是什么?我想在正常启动情况下保留启动画面。但在第二种情况下,重新创建应用程序时,我不确定如何处理它。有没有办法在返回重新创建的Main活动之前再次显示启动屏幕并等待?

class MyApplication : Application() {

    private val scope = CoroutineScope(Dispatchers.Main)

    companion object {
        lateinit var version: Integer
        var startupFinishedListener: (() -> Unit)? = null
    }

    override fun onCreate() {
        super.onCreate()
        scope.launch {
            version = getVersionFromNetwork() //Fake suspending network call
            startupFinishedListener?.invoke()
        }
    }
}
class SplashScreen : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.splash)
        MyApplication.startupFinishedListener = {
            startMainActivity()
        }
    }

    fun startMainActivity() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }
}
class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        //This line will crash if we are coming from an activity recreation
        Timber.d("Version is: ${MyApplication.version}")
    }
}

我不希望通过在onResume我的所有活动中工作而不是onCreate(). 理想情况下,我可以告诉 Android 在启动恢复的活动之前启动我的 Splash 活动。

4

2 回答 2

2

“这看起来像是一个架构问题。”

将 API 调用到应用程序类中并将其注册为您的活动的侦听器是一个坏主意!

有几个选项供您处理您的要求:

  1. 如果你想要的数据在 MainActivity 中真的很重要,你可以在加载实际数据之前调用 MainActivity onCreate() 本身的 API,并带有一些加载指示器。

如果在这种情况下重新启动进程会发生什么?

您的 MainActivity 将重新创建并再次调用 API。所以,你很好。

  1. 如果您需要在 MainActivity 启动时立即获取该数据,而无需等待,则需要进行缓存。在启动活动中调用您的 API 并将数据保存到文件、共享首选项或数据库中。然后访问 MainActivity 中的缓存数据。

如果在这种情况下重新启动进程会发生什么?

由于您已经将数据缓存到持久存储中,因此即使在进程重新启动后它也会存在。因此,您可以取回您的数据。

奖金

如果您不想每次打开应用程序时都使用缓存数据,只需清除 SplashActivity 中的缓存并每次调用 API 以获取最新数据,然后再转到 MainActivity。

于 2020-02-20T14:41:05.777 回答
2

您必须在 onResume() 生命周期中处理此问题。您可以创建一个 onResume,然后调用 SplashActivity 意图并完成()您的 MainActivity。这样,它只会返回到启动画面,在那里它将加载数据并再次调用主活动

override fun onResume() {
     super.onResume()
     val intent = Intent(this,SplashActivity)
     startActivity(intent)
}
于 2020-01-03T19:54:50.313 回答