iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 25
1
Mobile Development

程式初學:Android與Kotlin系列 第 25

Day 25--Lifecycles and logging(上)

  • 分享至 

  • xImage
  •  

對於app的許多動作,都需要瞭解lifecycle

本篇為google的教學文章,利用logging來觀察android lifecycles
activity每一個當下都有lifecycle的狀態,有以下幾種 (圖1)

An activity will do all setup of "global" state in onCreate()

onCreate()是每個activity必須首先執行的function
因為layout是透過onCreate()去inflate
當activity一初始化後,就會呼叫onCreate(),也只有在初始化後呼叫這一次,之後就會進入其它生命週期
接著須立刻呼叫super.onCreate()

  • 所有 Activity 的子類別都必須呼叫其父類別的同一個方法

這裡是呼叫父類別Activity下的onCreate()以確保父類別所做的初始化都有做到

看Logcat

super.onCreate()後加上

Log.i("MainActivity", "onCreate Called")

Log的用法.i表示information,第一個參數是tag,方便在logcat查詢時過濾訊息,通常會使用此class的name
第二個參數就是我們想要看到的訊息

在android studio執行run之後,到下方的Logcat console
在搜尋欄打我們要看的tag,此處為I/MainActivity(分大小寫)

  • I表示來自Log.i()
  • MainActivity表示我們自訂的Log.i("MainActivity", "onCreate Called")第一個參數

這樣就表示要顯示符合我們條件的訊息(Log.i()的第二個參數 "onCreate Called")

當看到符合的訊息出現時,就表示這行Log所在位置的程式已被執行
這裡也就是說onCreate()已執行

onStart()

緊接在onCreate()後的是onStart()
要onStart()執行之後,activity才會顯示在螢幕上
與onStart()相應的是onStop(),當app被滑掉不顯示在當前螢幕(按home鍵)時,activity會依照圖1的lifecycle箭頭方向,由onStart()走到onStop
等待將app叫回當前螢幕後,如logcat顯示不會回到onCreate(),是再次onStart(),並且是顯示回到activity被滑掉時最後狀態(這裡不知道是否因為onCreate()的savedInstanceState參數保存關係?)

若是用back返回鍵退出app,即使用最近程式(方塊鍵)叫回app,就會重新再進onCreate()

Timber

Timber是一個logging library,它會自動將其所在class的name當做tag
要使用Timber需要到dependencies implementation它
首先去 Timber project on GitHub,找目前的版本號並複製整行文字,例如implementation 'com.jakewharton.timber:timber:4.7.1'
回到專案,開啟build.gradle(Module:app),貼在dependencies區塊中

dependencies {
   ...
   implementation 'com.jakewharton.timber:timber:4.7.1'
}

再來建立一個Application class
這是一個基礎class,也是一個主要物件被android用來與app之間互動,即使我們不去指定(通常也無需指定),android也會為app建立一個Application物件
在整個app的activity被初始化前,Application class就會先創建
因為Timber是整個app都會用到的logging library,需要在其它設定之前先初始化,因此要在Application class中先執行

建立自訂的Application class並繼承Application(),例如
class ClickerApplication : Application() {..}
override其中的onCreate(),加入Timber並初始化,,全部像這樣

class ClickerApplication : Application() {
    override fun onCreate(){
        super.onCreate()

        Timber.plant(Timber.DebugTree())
    }
}

不是用default Application的話,我們就要到AndroidManifest.xml指明我們要改用的Application叫啥,不然app還是會用default Application,也就沒有Timber

<application
   android:name=".ClickerApplication"

準備完成後,就可以將Log.i()改成Timber,不用再給tag
Timber.i("onCreate called")
接著override其它的lifecycles來做觀察

    override fun onResume() {
        super.onResume()
        Timber.i("onResume Called")
    }

    override fun onPause(){
        super.onPause()
        Timber.i("onPause")
    }

    override fun onStop(){
        super.onStop()
        Timber.i("onStop Called")
    }

    override fun onDestroy(){
        super.onDestroy()
        Timber.i("onDestroy Called")
    }

    override fun onRestart(){
        super.onRestart()
        Timber.i("onRestart Called")
    }


上圖可以看到一執行app,就會有三個週期接續執行
由onCreate() -> onStart() -> onResume()
分別代表

  • onCreate() to create the app.
  • onStart() to start it and make it visible on the screen.
  • onResume() to give the activity focus and make it ready for the user to interact with it.
    要注意的是,onResume()雖然有個Resume,但不只是需要恢復activity時,一開始也會執行它

再來用back鍵來完全關閉activity,可以看到llifecycle走到onDestroy()

當onDestroy()執行時,表示activity已完全結束,可以被Garbage collection
OS知道可以將這個物件從記憶體中清除掉,讓資源釋放出來

codelab這裡寫到

Your activity may also be completely shut down if your code manually calls the activity's finish() method, or if the user force-quits the app. (For example, the user can force-quit the app in the recents screen by clicking the X in the corner of the window.) The Android system may also shut down your activity on its own if your app has not been on-screen for a long time.

finish():Call this when your activity is done and should be closed.

請教EnPing有關finish()與onDestroy()的差別後,有稍微了解一些:
原來所有onXXXX()的方法,都不應該由我們呼叫,應該說lifecycle是由系統依照app被使用的情況而去呼叫
那finish()是我們可以另外告訴系統要把activity給結束掉的方法
當系統收到我們的程式碼呼叫finish()時,就會把activity註記為不要的物件,然後準備onPause(),onStop(),onDestory(),但呼叫這些lifecycle的時間依然是由系統控制,依情況可能快可能慢

這裡有一個重點是:
onCreate()和onDestroy()這二個頭尾,只會在那個activity物件的生命週期各被呼叫一次

  • onCreate() to initialize the app for the very first time
  • onDestroy() to clean up the resources used by your app

上一篇
Day 24--天氣app(十)取得所在位置 part 2
下一篇
Day 26--Lifecycles and logging(中)
系列文
程式初學:Android與Kotlin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言