Kotlin Android 實戰(一)閃屏頁面
阿新 • • 發佈:2019-02-09
看了一些kotlin的語法,但是總覺得不真正寫一下不行。
聽說kotlin和java完全相容,寫了寫發現,最小單位是類(java類中不能寫kotlin程式碼,反之亦然)。
想在新專案中嘗試一下的同學不要有顧慮,就像當初使用mvvm,mvp一樣,實在不行在換回java唄(哈哈哈)。
本篇從kotlin安裝開始到編寫一個簡單的閃屏頁面練練。
首先AS安裝kotlin外掛:
然後重啟as,在專案的project的gradle中新增:
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.2"
然後是app下的gradle中新增:
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt'
kapt {
generateStubs = true
}
dependencies {
.../
kapt 'com.android.databinding:compiler:2.3.0'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
然後建立一個Activity,這時建立的activity就不是我們原來的.class檔案了,建立的是.kt檔案:
建立之後,分析下我們閃屏會用到Handler來發送延時訊息,直接使用handler可能會造成記憶體洩漏,所以我們去自定義個弱引用的handler。
原來java的寫法:
/** * 採用弱引用handler 防止記憶體洩漏 * Created by ge on 2017/2/16. */ public class UIHandler<T> extends Handler { protected WeakReference<T> ref; public UIHandler(T cls){ ref = new WeakReference<T>(cls); } public T getRef(){ return ref != null ? ref.get() : null; } }
改成kotlin之後:
/**
* 採用弱引用handler 防止記憶體洩漏
* Created by ge on 2017/2/16.
*/
open class UIHandler<T>(cls: T) : Handler() {
protected var ref: WeakReference<T>? = null
init {
ref = WeakReference(cls)
}
fun getRef(): T? {
return if (ref != null) ref!!.get() else null
}
}
可能一開始,我們直接轉會遇到很多語法上的問題,as給我們提供了一個便捷通道,一鍵直接從java檔案轉成kotlin檔案:
我建議,大家如果是跟我一樣剛開始接觸,還是試著練習一點點寫,鍛鍊鍛鍊,如果實在寫不出來就轉換之後有個參照(小白小白小白)。
而且自動轉換畢竟是按照你不知道的規則轉,轉的對錯與否我也不知道。
好了,定義完handler之後就在SplashActivity中使用了,首先定義幾個常量:
// 將常量放入這裡
companion object {
// 正常跳轉到登入介面 常量 防止以後增加業務邏輯
val MSG_LAUNCH : Int = 0
// 延時時間
val SLEEP_TIME = 3000
}
再定義我們的Handler:
private class SplashHandle(cls : SplashActivity) : UIHandler<SplashActivity>(cls) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
val activity = ref?.get()
if (null != activity){
if (activity.isFinishing)
return
when(msg?.what){
// 正常跳轉到登入介面
MSG_LAUNCH -> {
activity.startActivity(Intent(activity, LoginActivity::class.java))
activity.finish()
}
}
}
}
}
注:java中的switch換成了when。
private val mHandler = SplashHandle(this)
定義runnable:
val runnable = Runnable {
kotlin.run {
val message = mHandler.obtainMessage(MSG_LAUNCH)
mHandler.sendMessage(message)
}
}
注:這裡出現了var 和 val兩個宣告欄位,
var是宣告可變的變數。
val是宣告一個只讀變數,可以理解為java中的final,宣告的時候必須初始化,生命之後不能改變她的值。
一系列準備工作做好之後就是最後一步呼叫了,我這裡在onResume中使用:
override fun onResume() {
super.onResume()
val start = System.currentTimeMillis()
/*
這裡計算了兩個時間
兩個時間間可以放入判斷條件:是否需要自動登入等
*/
var costTime = System.currentTimeMillis() - start
val left = SLEEP_TIME - costTime
// kotlin中取消了java中的三目運算,換成if...else...
mHandler.postDelayed(runnable, if(left > 0) left else 0)
}
上面沒有提到我們Activity的頭部(onCreate),因為裡面只有一個setContentView。
setContentView和原來沒啥區別,除了java檔案替換成.kt檔案之外的檔案都沒有變。
最後貼出閃屏頁面的完整程式碼:
package com.reliable.mihophysical.ui
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Message
import com.reliable.baselib.utils.UIHandler
import com.reliable.mihophysical.R
import com.reliable.mihophysical.ui.login.LoginActivity
/**
* 閃屏介面
* by ge
*/
class SplashActivity : AppCompatActivity() {
private val mHandler = SplashHandle(this)
// 將常量放入這裡
companion object {
// 正常跳轉到登入介面 常量 防止以後增加業務邏輯
val MSG_LAUNCH : Int = 0
// 延時時間
val SLEEP_TIME = 3000
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
}
override fun onResume() {
super.onResume()
val start = System.currentTimeMillis()
/*
這裡計算了兩個時間
兩個時間間可以放入判斷條件:是否需要自動登入等
*/
var costTime = System.currentTimeMillis() - start
val left = SLEEP_TIME - costTime
// kotlin中取消了java中的三目運算,換成if...else...
mHandler.postDelayed(runnable, if(left > 0) left else 0)
}
val runnable = Runnable {
kotlin.run {
val message = mHandler.obtainMessage(MSG_LAUNCH)
mHandler.sendMessage(message)
}
}
// 弱引用handler內部類
private class SplashHandle(cls : SplashActivity) : UIHandler<SplashActivity>(cls) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
val activity = ref?.get()
if (null != activity){
if (activity.isFinishing)
return
when(msg?.what){
// 正常跳轉到登入介面
MSG_LAUNCH -> {
activity.startActivity(Intent(activity, LoginActivity::class.java))
activity.finish()
}
}
}
}
}
}