官术网_书友最值得收藏!

3.2 使用ViewModel解決廣告引導(dǎo)頁屏幕旋轉(zhuǎn)問題

在上一節(jié)中提到了ViewModel類可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后讓數(shù)據(jù)繼續(xù)留存,這時(shí),細(xì)心的讀者就會思考了,該如何使用ViewModel來解決廣告引導(dǎo)頁屏幕旋轉(zhuǎn)問題呢?

在使用ViewModel之前,先引入ViewModel的依賴項(xiàng),代碼如下:

def lifecycle_version = "2.3.1"
implementation
"androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"

然后新建一個(gè)繼承自ViewModel的AdvertisingViewModel類,在該類中聲明計(jì)時(shí)起始變量millisInFuture,代碼如下:

class AdvertisingViewModel : ViewModel() {
    /**
     * 計(jì)時(shí)開始時(shí)間,默認(rèn)5秒
     */
    var millisInFuture: Long = 5000
}

若開發(fā)者想在ViewModel類中使用資源文件,則要使用到Context上下文了。這里要注意的是,一定不能將Activity的上下文傳給ViewModel,否則會存在內(nèi)存泄漏的風(fēng)險(xiǎn)。這一點(diǎn)本書后面會有詳細(xì)的講解。那這里該如何處理呢?只需要將父類ViewModel修改為AndroidViewModel即可。示例如下:

class AdvertisingViewModel(application: Application) :
AndroidViewModel(application) {
    /**
     * 計(jì)時(shí)開始時(shí)間,默認(rèn)5秒
     */
    var millisInFuture: Long = 5000
}

擁有Application的實(shí)例之后就可以訪問資源文件了。在Activity中初始化ViewModel,示例如下:

private lateinit var advertisingViewModel: AdvertisingViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        advertisingViewModel = ViewModelProvider(this).get(AdvertisingViewModel::class.java)
        ...
}

接下來只需要將原Activity中的millisInFuture變量統(tǒng)一替換為AdvertisingView-Model中的millisInFuture即可。示例代碼如下:

class AdvertisingActivity : AppCompatActivity() {
    ...
    private lateinit var advertisingViewModel: AdvertisingViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_advertising)
        advertisingViewModel = ViewModelProvider(this).get(AdvertisingViewModel::class.java)
        val advertisingManage = AdvertisingManage(advertisingViewModel.millisInFuture)
        lifecycle.addObserver(advertisingManage)
        tvAdvertisingTime = findViewById(R.id.tv_advertising_time)
        advertisingManage.advertisingManageListener =
            object : AdvertisingManage.AdvertisingManageListener {
                override fun timing(second: Int) {
                    tvAdvertisingTime.text = "廣告剩余$second秒"
                    advertisingViewModel.millisInFuture = second.toLong() * 1000
                }
            }
        ...
    }
}

運(yùn)行程序,當(dāng)廣告剩余2秒的時(shí)候,旋轉(zhuǎn)屏幕,打印的日志如圖3-4所示。

038-1

圖3-4 廣告剩余2秒時(shí)旋轉(zhuǎn)屏幕的日志

從日志中可以看出,廣告剩余2秒的時(shí)候,由于旋轉(zhuǎn)屏幕停止計(jì)時(shí)了,因此旋轉(zhuǎn)后會繼續(xù)從1秒鐘開始計(jì)時(shí),這與使用onSaveInstanceState方法實(shí)現(xiàn)的效果相同。但是從代碼中可以很明顯地看出,使用ViewModel遠(yuǎn)比使用onSaveInstanceState簡潔,這一切都得益于ViewModel的生命周期。

主站蜘蛛池模板: 临洮县| 阳朔县| 皮山县| 日照市| 大兴区| 沁水县| 博爱县| 新宾| 孝感市| 灵武市| 辉县市| 旺苍县| 大石桥市| 恭城| 德安县| 丹寨县| 大理市| 长垣县| 西平县| 大田县| 庆元县| 铁力市| 同仁县| 连平县| 萨迦县| 忻城县| 高淳县| 大连市| 图木舒克市| 神木县| 隆回县| 阜城县| 富宁县| 扎兰屯市| 麟游县| 天台县| 分宜县| 土默特右旗| 怀柔区| 富裕县| 沈丘县|