主頁 > 移動端開發 > Kotlin快速上手

Kotlin快速上手

2022-04-15 08:21:04 移動端開發

一、Kotlin基礎

1.資料型別宣告

在Kotlin中要定義一個變數需要使用var關鍵字

//定義了一個可以修改的Int型別變數
var number = 39

如果要定義一個常量可以使用val關鍵字,等價于Java的final關鍵字.

val name = "miku"

//給val定義的常量再次賦值就會提示錯誤
name = "ミク"

在Kotlin中要宣告一個資料型別必須要使用var或者val來定義.

2.資料型別

Kotlin的資料型別分為基本資料型別和參考資料型別.

基本資料型別:Boolean、Number、Char

參考型別:可空型別、Object、陣列型別

Kotlin中的Number型別泛指所有跟數字有關的型別,int、float、double、long

//java.lang.Integr  Int--->int
var intNumber:Number = 39

//java.lang.Float   Float--->float
var floatNumber:Number = 39.0f

//java.lang.Double   Double--->double
var doubleNumber:Number = 39.000000000000000

//java.lang.Long   Long--->long
var longNumber:Number = 39L

2.1.Kotlin預定義的基本資料型別

var intType:Int = 39 //int

var shortType:Short = 39 //short

var byteType:Byte = 0 //byte

var boolType:Boolean = true //boolean

var stringType:String = "miku" //String

var floatType:Float = 39f //float

var doubleType:Double = 39.0000000000 //double

var longType:Long = 39L //long

var numberType:Number = 39 //Integr、Float、Double、Long

var charType:Char = '0' //char

字串拼接,通過${}直接參考變數,不再需要引號 + 引號的方式

val name = "komine"
val text = "私の名前は${name}と申します,"

print(text)

2.2.元組

元組是一個固定長度,且不能被修改的資料結構

//二階元組
var person1 = Pair("komin",16)

//三階元組
var person2 = Triple("komine",18,"女")

person2.first //第一個元素的值
person2.second  //第二個元素的值
person2.third   //第三個元素的值
  

Kotlin的元組其實就是一個泛型物件的封裝.通過反編譯生成的.class檔案可以看出,二階元組其實是對應Pair類,

三階元組其實是對應Triple類. first、second、third分別對應getFirst()、getSecond()、getThrid()方法.

如果用Java來實作的話差不多就是下面這個樣子,可以看到,元組不過是Kotlin在原始碼階段提供的一種更方便的語法而已.

public class MyPair<First,Second> {

    private final First mFirstValue;
    private final Second mSecond;

    public MyPair(First first, Second second){
        this.mFirstValue = https://www.cnblogs.com/komine/p/first;
        this.mSecond = second;
    }

    public First getFirst() {
        return mFirstValue;
    }

    public Second getSecond() {
        return mSecond;
    }
}

2.3.可空型別

Kotlin定義了一種可以為空的資料型別,只有宣告為可空型別的變數才能將null賦值于它.默認宣告的型別全部都是非空型別.

var str:String? = null  //在型別的后面添加?表示該型別可空

print(str?.length)  //通過?.方式來訪問可空型別的成員方法或變數,如果str是null則后面的呼叫會回傳null,不會報錯

//如果你明確知道,str在某個時候肯定不為空,可以通過!!操作該變數,但如果str為空則會拋出空指標例外
print(str!!.length)

2.4.陣列

在Kotlin中定義一個陣列非常簡單.呼叫arrayOf()即可創建一個陣列.

var names = arrayOf("miku","rin","luka")
var numbers = arrayOf(16,14,17)

//跟Java一樣,也可以通過[下標]的方式訪問陣列的元素
print(names[0])

//創建一個指定長度的陣列,值為null
var fixedArray = arrayOfNulls<Int>(39)

//創建一個空陣列
var emptyArray = emptyArray<Int>()

2.5.集合

Kotlin的集合分為可變集合和不可變集合.可變集合都是由Mutable開頭的.

可變集合

//MutableList集合,該集合可以包含相同元素
var mutableList = mutableListOf("miku","rin","luka")

//鍵值對,包含Key和Value的集合
var mutableMap = mutableMapOf<String,String>()
var linkedHashMap = linkedMapOf<String,String>() //等價mutableMap

//MutableSet集合,該集合不會出現相同的元素,如果集合已經包含某個值,添加的時候會忽略添加操作
var mutableSet = mutableSetOf<Object>()
var linkedSet = linkedSetOf<String>() //等價mutableSet

不可變集合

//List集合,無法進行添加操作
var list = listOf("miku","rin","luka")

//Map集合,無法進行添加操作
var map = mapOf(Pair("miku",16))
var linkedMap = 

//Set集合,無法進行添加操作
var set = setOf<Int>(0,1,2,3,4,5,6,7,8,9)

2.5.1擴展方法

toList() 回傳一個不可變List集合

toMap() 回傳一個不可變的Map集合

toSet() 回傳一個不可變的Set集合

2.5.2集合操作

類似.Net中的Linq查詢

any 判斷集合中是否有滿足條件的元素

var mutableList = mutableListOf("miku","rin","luka")

val result:Boolean = mutableList.any(){
    it == "miku" //有一個元素的值為miku
}

all 判斷集合中的所有元素是都否滿足條件

var mutableList = mutableListOf("miku","rin","luka")

val result:Boolean = mutableList.all(){
    it.isNotEmpty() //元素的長度大于0
}

none 判斷集合中的所有元素是否都不滿足條件,滿足則回傳true

var mutableList = mutableListOf("miku","rin","luka")

val result:Boolean = mutableList.none(){
    it.isNotEmpty()  //元素的長度等于0  false
}

count 回傳滿足條件的元素個數,類似sql中的select count(*) from table where xx = xx

var mutableList = mutableListOf("miku","rin","luka")

val result: Int = mutableList.count {
    it == "miku"  //回傳集合中元素值為miku的元素個數
}

reduce 從第一個元素到最后一個元素的累加

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result: Int = numbers.reduce() {
    sum: Int, i -> sum + i  //sum:宣告一個用于接收累加結果的變數 i->:回圈每一個元素,sum + i:累加每個元素到sum
}

reduceRight 從最后一個元素到第一個元素的累加

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result: Int = numbers.reduceRight() {
    sum: Int, i -> sum + i
}

fold 跟reduce類似,不過可以設定初始化,從初始值開始累加

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result: Int = numbers.fold(10){
    sum, i -> sum + i
}

foldRight...

sumOf 回傳集合中所有元素的總和,該集合的元素必須是Number型別

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.sumOf{
    it
}

dropWhile 去除滿足條件的元素,直到不滿足為止,回傳剩余元素的集合

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.dropWhile {
    it < 5
}

filter 過濾不滿足條件的元素,回傳滿足元素的新集合

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.filter {
    it < 5
}

filterNot 過濾滿足條件的元素,回傳不滿足元素的新集合

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.filterNot {
    it < 5
}

take 回傳從第一個元素開始的N個元素

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.take(5)   //{1,2,3,4,5}

takeLast 回傳從最后一個元素開始的N個元素

...

takeWhile 回傳從第一個元素開始符合給定條件的元素

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.takeWhile {
    it > 0
}

drop 回傳去掉N個元素之后的串列

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.drop(1)

dropLastWhile 回傳從最后一個元素開始,去掉滿足條件的元素

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.dropLastWhile {
    it > 5
}

slice 保留指定下標對應的元素

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.slice(listOf(1,2,3))

map 將集合中的元素通過某種方法轉換后,回傳一個新集合

val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
val result = numbers.map {
    val diff = 10
  
    it * diff
}

后續更新...

2.6.型別轉換

Kotlin通過as關鍵字將一個型別轉換為另一個型別.

var numberType:Number = 39
var intType:Int = numberType as Int

Kotlin可以通過 is 關鍵字自動完成裝箱的操作.

open class GameConsole{

}

class PS4 : GameConsole() {

}

class NintendoSwitch : GameConsole() {
    public val version = "10.0"
}

fun main(args: Array<String>) {
    val gameConsoles = arrayOf(PS4(),NintendoSwitch())
    val gameConsole = gameConsoles[1]

    //會自動完成裝箱操作,在當前呼叫范圍內將gameConsole識別NitendoSwitch,可以直接訪問物件的成員,不需要手動轉換
    if(gameConsole is NintendoSwitch){
        print(gameConsole.version)
    }
}

3.運算子

Kotlin特有的運算子有===、!==

3.1.恒等和非恒等

判斷兩個物件之間的地址是否相等

var obj1 = Object()
var obj2 = Object()

if(obj1 === obj2){
    println("恒等")
}

if(obj1 !== obj2){
    println("非恒等")
}

3.2.位運算

只有Int和Long型別可以使用.

val i:Int = 10
val j:Int = 20

val result = i shl j //有符號左移
result = i shr j //有符號右移
result = i ushr  //無符號右移
result = i and j  //按位與
result = i or j  //按位或
result = i xor  //按位異或
result = i inv j  //按位取反

3.3.區間運算子

表示某個值是否在某個范圍或者集合之中.

//i >=0 && i <= 100
if(i in 0..100){
    print(i)
}

陣列或者集合是否包含某個值

val names = arrayOf("miku","rin","luka")
if("miku" in names){
    print("包含")
}

4.條件陳述句

when是Kotlin提供類似Java中Switch的條件陳述句.它能做到Switch能做到的所有事,并且還提供了更方便的語法.

fun test(i:Int){
    when(i){

        // case 1
        1 ->{

        }

	//case 2
        2 -> {

        }

 	//i >= 3 && i <= 9
        in 3..9 ->{

        }

	//default
        else ->{

        }
    }
}

when如果不提供引數也可以當作if elseif使用

5.回圈陳述句

跟Java的使用差別不大,一般配合區間運算子in來更簡便的使用

val names = arrayOf("miku","rin","luka")
for (name in names){
    println(name)
}

//遍歷陣列或集合帶索引
for ((index,name) in names.withIndex()){
  
}

val i = 0
for (i in 0..99){  //i = 0;i <= 99;i++
    println(i)
}

var i = 10
while (i > 0){
    println(i)
    i--
}

do {
    i--
    println(i)
}while (i > 0)

//foreach
val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
numbers.forEach{ it ->
    println(it)
}

//foreach 帶索引
val numbers = mutableListOf(1,2,3,4,5,6,7,8,9)
numbers.forEachIndexed{index, i ->  
    println("index[${index}] = $i")
}

6.函式

Kotlin中定義函式使用fun關鍵字.如果方法不需要回傳值可以不寫,或者寫Unit

fun sum(number1:Int,number2:Int):Int{
    return number1 + number2
}

6.1默認引數

Kotlin中添加了默認引數的支持,當一個方法指定了引數的默認值,則呼叫的時候可以不提供該引數的值.

要使用默認引數,在引數的后面添加=進行賦值操作.

fun sum(number1:Int,number2:Int = 0):Int{
    return number1 + number2
}

6.2可變引數

和Java一樣,Kotlin也提供可變引數的支持,使用vararg關鍵字宣告可變引數

fun sum(vararg number:Int){
    //number在使用的時候其實是一個陣列型別的變數,可以呼叫陣列的一些方法
}

6.3Lambda運算式

Lambda運算式可以看作是一個匿名的函式.

var execute:(Int,Int) -> Int = {x,y ->
    x * y
}

println(execute(10,10))

如果函式只有一個引數時可以省略不寫,這個時候用it來表示

var execute:(String) -> String = {
    it
}

println(execute("komine"))

6.4高階函式

Kotlin支持將函式作為引數或者回傳值,包含這樣操作的函式稱為高階函式.將函式作為引數時使用雙冒號::來傳遞.

fun main(args: Array<String>) {
   call(::method)
}

fun call(m:(number:Int) -> Int){
    println(m(39))
}

fun method(number:Int):Int{
    return number * number
}

也可以使用Lambda運算式來表示一個匿名引數.

call{number: Int -> return@call number * number }

Kotlin本身也提供了一些高階函式供我們使用,比如apply函式,在Android中初始化變數可以這樣寫.

var paint = Paint().apply {
    this.isAntiAlias = true
    this.color = Color.BLACK
    this.style = Paint.Style.STROKE
    this.strokeWidth = 10f
}

6.5行內函式

Kotlin支持行內函式,跟C++的行內函式作用一致,因為函式的執行有壓堆疊和出堆疊的步驟,會帶來一定的開銷.

在將函式宣告為行內函式的時候,在編譯的時候,編譯器會在所有呼叫函式的地方,將函式呼叫直接替換成函式體的內容.

一般來說,行內函式中的嵌套邏輯不能太復雜,C++的行內函式是否替換是由編譯器決定的,Kotlin會按照inline關鍵直接替換.

通過反編譯生成的class檔案可以看到,行內函式就是直接將有函式呼叫的地方,直接替換成函式體的內容.

fun main(args: Array<String>) {
    test()
}

inline fun test(){
    for (i in 0..99){
        println(i)
    }
    for (i in 0..99){
        println(i)
    }
    for (i in 0..99){
        println(i)
    }
    for (i in 0..99){
        println(i)
    }
    for (i in 0..99){
        println(i)
    }
    for (i in 0..99){
        println(i)
    }
}

反編譯結果

如果函式的引數中有函式引數型別或者Lambda運算式,也可以使用noinline關鍵字指定不引數行內的函式.

crossinline關鍵字待補充...

二、Kotlin進階

1.協程

協程是跑在執行緒上的產物,它擁有自己的堆疊記憶體和區域變數,被稱為輕量級Thread.它的內部實作是由編譯器來完成的.

官方檔案說明

在使用協程之前,需要添加依賴

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'

簡單用法

GlobalScope.launch(context = Dispatchers.Default, start = CoroutineStart.DEFAULT) {
    //延時1.5秒
    delay(1500L)
    println("當前執行緒:" + Thread.currentThread().name)
    println("World")
}
println("Hello,")
println("當前執行緒:" + Thread.currentThread().name)
Thread.sleep(3000L)

context:協程的背景關系,這里設定的是CoroutineDispatch協程運行的執行緒調度器,它有四種執行緒模式:

Dispatchers.Default //默認

Dispatchers.IO //作業在其他執行緒

Dispatchers.Main //主執行緒

Dispatchers.Unconfined //不指定就是在當前執行緒,kotlinx.coroutines.DefaultExecutor

也可以自己創建一個協程背景關系,這個背景關系也可以理解為協程所運行在的執行緒.

val context = newSingleThreadContext("single")

start:啟動模式,默認是CoroutineStart.DEFAULT,就是創建之后就會啟動

CoroutineStart.DEFAULT

CoroutineStart.ATOMIC

CoroutineStart.UNDISPATCHED

CoroutineStart.LAZY 懶加載模式,它會回傳一個Job物件,你可以手動開啟它.

val job = GlobalScope.launch(context = Dispatchers.Default, start = CoroutineStart.LAZY) {
    //延時1秒
    delay(1500L)
    println("當前執行緒:" + Thread.currentThread().name)
    println("World")
}
println("Hello,")
println("當前執行緒:" + Thread.currentThread().name)

job.start()

Thread.sleep(3000L)

GlobalScope.async 帶回傳值

suspend fun main(args: Array<String>) {
    val result = GlobalScope.async {
        delay(1000L)
        return@async "async"
    }

    println(result.await())
    Thread.sleep(3000)
}

async會阻塞當前協程,會等待當前協程執行完畢,呼叫await()的函式需要使用suspend關鍵字修飾.

協程的掛起,suspend表示當前協程被掛起.

fun main(args: Array<String>) {
    GlobalScope.launch {
        //get方法是被suspend修飾的,表示呼叫時會將當前協程掛起
        val str = get()
        //會等待get()執行完畢才會繼續執行
        printStr(str)
    }
    //防止行程結束
    Thread.sleep(3000L)
}

suspend fun get():String{
    println("get()正在執行..")
    delay(1000)

    return "data"
}

suspend fun printStr(str:String){
    println(str)
}

協程之間也可以嵌套,呼叫await會阻塞外部協程,代碼還是會按順序運行

fun main(args: Array<String>) {
    GlobalScope.launch {
        val str = GlobalScope.async {
            return@async get()
        }.await()

        GlobalScope.launch{
	    printStr(str)
        }
    }
    //防止行程結束
    Thread.sleep(3000L)
}

suspend fun get():String{
    println("get()正在執行..")
    delay(1000)

    return "data"
}

suspend fun printStr(str:String){
    println(str)
}

待補充...

2.面向物件

2.1類的宣告

和很多語言一樣,Kotlin使用class關鍵字來宣告一個類.

class Person{

}

2.1.1內部類

class Person{
    //內部類的宣告使用inner關鍵字修飾
    inner class Info{
  
    }
}

要實體內部類需要先實體化主類

val person = Person("miku")
val info = person.Info()

2.1.2資料類

通過data class 修飾的類稱為資料類,資料類必須提供一個有參的建構式.資料類一般不定義方法.

data class MyData(val height:Float,val weight:Float,val money:Float){

}

2.1.3列舉類

跟Java的列舉類使用基本相同.

enum class DirectionEnum{
    East{
        override fun move() {

            //name:當前列舉常量的名稱
            //ordinal:當前列舉常量的值
	    println("name$name")
            println("value:$ordinal")
        }
    },
    South{
        override fun move() {

        }
    },
    West{
        override fun move() {

        }
    },
    North{
        override fun move() {
  
        }
    };
    abstract fun move();
}

2.1.4密封類

emm...不知道怎么用,后面補充

2.1.5抽象類

使用abstract關鍵字宣告一個抽象類

open abstract class Person(name:String, age:Int){
  
}

2.2建構式

Kotlin的建構式可以直接寫在類名的后面,稱為主建構式,這樣定義的建構式是沒有方法體的,要執行初始化操作

可以使用init代碼塊.

open class Person(name:String, age:Int){

    init {
        println("主建構式執行...")
        println("name:${name},age = $age")
    }
}

2.2.1 副建構式

通過constructor定義的建構式稱為副建構式,需要間接呼叫主建構式進行初始化

fun main(args: Array<String>) {
    val person = Person("miku")
}

open class Person(name:String, age:Int){

    init {
        println("主建構式執行...")
        println("name:${name},age = $age")
    }

    //副建構式需要間接呼叫主建構式通過this關鍵字
    constructor(name:String) : this(name,16) {
        println("副建構式執行...")
    }
}

2.3繼承

如果想讓一個類可以被其他類繼承,需要在類的宣告之前加上open關鍵字,使用:冒號來繼承

open class Person{
    open fun take(){}
}

class Student : Person() {

}

如果子類想重寫父類定義的方法,該方法必須是open關鍵字修飾的方法,抽象方法的修飾符默認是open.

2.4靜態成員

Kotlin沒有提供static關鍵字,如果想實作Java那樣的靜態成員呼叫可以使用companion object代碼塊來定義靜態成員.

在Kotlin中稱為伴生物件,用伴生物件的成員來代替靜態成員.

class PS4{
    companion object{
        val FIRMWARE_VERSION:Float = 10.0f
        fun boot(){
            println("boot...")
        }
    }
}

跟Java一樣,然后通過類名呼叫靜態成員

PS4.boot()
PS4.FIRMWARE_VERSION

2.5介面

使用interface來宣告一個介面.與Java的用法并無二致

interface Callback{
    fun onSuccess()
    fun onFailed()
}

3.泛型

基本使用和Java一致

class Data<T>(private val data:T){
    fun get():T{
        return data
    }
}
val data1 = Data("String")
println(data1.get())

val data2 = Data(16)
println(data2.get())

3.1out和in關鍵字

Kotlin中使用out和in來代替? extends 和? super使用,具體用法跟Java是類似的.

fun main(){
    val ps4List = mutableListOf<PS4>()

    setGameConsoles(ps4List)
  
    val gameConsoles = getGameConsoles()
    for (gameConsole in gameConsoles){
        val ps4 = gameConsole as PS4
        ps4.play()
    }
}

// out ----> ? extends GamesConsole
fun setGameConsoles(gamConsoles:MutableList<out GameConsole>){
   
}

//in -----> ? super PS4
fun getGameConsoles():MutableList<in PS4>{
    val gameConsoles = mutableListOf<GameConsole>()
    gameConsoles.add(PS4())
    gameConsoles.add(PS4())
    return gameConsoles
}

open class GameConsole{
    open fun play(){

    }
}

class PS4 : GameConsole(){
    override fun play() {
        println("ps4 play...")
    }
}

class NintendoSwitch : GameConsole(){
    override fun play() {
        println("ns play...")
    }
}

4.委托

其實就是代理設計模式.

4.1委托的使用場景

Java中的代理模式實作

//支付介面
public interface IPay {
    void pay();
}

//支付寶支付
public class AliPay implements IPay{
    private float mMoney;
    public AliPay(float money){
        mMoney = money;
    }

    @Override
    public void pay() {
        Log.d("Alipay","支付寶支付" + mMoney + "元...");
    }
}

//微信支付
public class WeChatPay implements IPay{
    private float mMoney;
    public WeChatPay(float money){
        mMoney = money;
    }

    @Override
    public void pay() {
        Log.d("WeChatPay","微信支付" + mMoney + "元...");
    }
}

//代理物件
public class ProxyPay implements IPay{
    private IPay mPay;
    public ProxyPay(IPay pay){
        mPay = pay;
    }

    @Override
    public void pay() {
        mPay.pay();
    }
}

Kotlin的代理模式實作

interface IPay{
    fun pay()
}

class Alipay(private val money:Float) :IPay{
    override fun pay() {
        println("支付寶支付$money...")
    }
}

class WeChatPay(private val money: Float) :IPay{
    override fun pay() {
        println("微信支付$money...")
    }
}

class PayDelegate(private val play:IPay) :IPay by play{
    //什么都不需要做,系統幫我們完成一系列操作
}

可以看出,Kotlin的委托其實就是簡化了代理模式的實作程序.

4.2屬性委托

將屬性的賦值操作交給其他類來代理.可以通過其他類來統一控制屬性的取值,合法性等等操作.

基本使用

//宣告一個介面,不一定要介面也可以是一個類
interface IPropertyDelegate

class PS4 :IPropertyDelegate{
    var version:String by DataDelegate()
}

class NintendoSwitch :IPropertyDelegate{
    var version:String by DataDelegate()
}

class DataDelegate {
    private var version:String = ""
    operator fun setValue(thisRef: IPropertyDelegate, property: KProperty<*>, value: String) {
        this.version = value
    }

    operator fun getValue(thisRef: IPropertyDelegate, property: KProperty<*>): String {
        return this.version
    }
}

當給PS4或者NintendoSwitch物件的version賦值的時候,就會去到DataDelegate物件的setValue()方法,達到統一賦值的操作,相同的操作不需要在每個類都寫一次

val ps4 = PS4()

ps4.version = "7.55"
println(ps4.version)

val ns = NintendoSwitch()

ns.version = "13.0"
println(ns.version)

5.其他

5.1擴展函式

給某個類添加一個擴展函式,其效果跟成員函式呼叫一致.一般定義到一個統一的檔案中,不需要先定義一個型別,直接寫就好

//給String擴展了一個first方法
fun String.first():Char{
    return this[0]
}

println("komine".first())

5.1擴展屬性

給某個類添加一個擴展屬性

val Int.dp:Int
    get(){
        //簡單模擬一下,開發中不是這么計算的
        return this * 1.5f.toInt()
    }

比如給Int型別添加了一個dp的擴展屬性,可以將int值轉換為對應的dp

val width = 39.dp

待更新...

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/458247.html

標籤:Android

上一篇:【Harmony OS】【ARK UI】ETS 的 List 實作下拉重繪功能實作

下一篇:Kotlin快速上手

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more