現在市面上的程式打開的時候,大部分都會有啟動畫面,等待裡面的處理程序處理好以後,再打開程式。在網路上也能看到各種不同的寫法,不過大致上的概念都是一樣的。
但其中我看到覺得最不好的寫法是:在 Splash Activity 的時候,使用固定的時間延遲開啟下一個 activity。在開發者不能夠確定使用者設備的狀態下,貿然延遲只會白白浪費時間。
我的做法是利用 coroutines 的 suspend function 防止長時間的處理讓系統自動停止
class SplashActivity: AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
很簡單,跟上面講的一模一樣,開啟 MainActivity 後 finish。
雖然沒有 setContentView(),但依然有畫面,是用了 Theme 設定背景。
用 layer-list 做了一個名為 spalsh_screen 的 drawable 當作背景
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/holo_green_light"/>
<item
android:drawable="@mipmap/ic_launcher_round"
android:gravity="center"/>
</layer-list>
在 styles.xml 中在做出一個 Theme 給 Splash Activity 用
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="SplashScreenTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item>
</style>
</resources>
最後記得,要在 AndroidManifest.xml 設定 Theme
android:theme="@style/SplashScreenTheme"
還有起始 activity 改成 Splash Activity
<activity android:name=".SplashActivity"
android:theme="@style/SplashScreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
class MainActivity : AppCompatActivity() {
private val textCalculate by lazy {
findViewById<TextView>(R.id.textMainCalculate)
}
var ans= sqrt(2.0)
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
setContentView(R.layout.activity_main)
super.onCreate(savedInstanceState)
MainScope().launch {
calculate()
}
textCalculate.text= ans.toString()
}
private fun calculate(){
for(i in 0.. 15000)
for(j in 0.. 15000)
ans= sin(asin(ans))
}
}
記得把 Theme 換回來
有一個負責長時間運算的 calculate() 方法。利用 coroutines 的機制,讓 android 不會自己把方法關閉。
結果如下。
如果沒有做成 coroutines 的話,畫面會是這樣子
如此一來就確定了,使用 coroutnes 的確可以完成 splash screen 的效果