用kotlin方式打開《第一行代碼:Android》


參考:《第一行代碼:Android》第2版——郭霖

注1:本文為原創,例子可參考郭前輩著作:《第一行代碼:Android》

注2:本文不贅述android開發的基本理論,不介紹入門知識,不介紹Android Studio基本安裝,開門見山,直接使用kotlin改寫郭前輩的《第一行代碼:Android》中的部分例子,有機會的話自己做一些新例子出來!

注3:本文基本以kotlin語言作為Android開發,偶爾涉及java作為對比

注4:開發基於Android Studio 3.0,並且新建項目時勾選“support kotlin”

看看精彩世界——使用網絡技術

原書9.2節:看看精彩世界——使用網絡技術(書p312)

原書采用了OkHttp開源項目作為請求類庫

我改為使用kotlin對Java.Net類擴展的URL類!

一些小知識:
kotlin是基於JVM的語言,他不像scala語言,重新構建了自己的生態,kotlin直接擴展了java的類庫,他的宗旨:“java有則用之,無則擴展之”,所以他能做到與java的100%兼容,這個優勢同樣被一起帶入了他的Android開發鄰域
(注:kotlin已成為了Google官推語言)

Anko類庫:

anko類庫不是kotlin自帶的標准庫,需要在gradle中添加擴展,gradle會自動下載anko和處理他的依賴
官網對anko的描述(也許你暫時不感興趣,可以跳過):https://github.com/Kotlin/anko

尋找anko:

上這個網址,搜索anko即可
http://mvnrepository.com/search?q=anko

點擊如圖箭頭里的包:

這里寫圖片描述

需要用到的是上圖中的其中三個,anko-sdk可以選擇23或者15,我選擇的是15。
另外兩個,一個個點進去,選擇gradle,復制里面的代碼:

這里寫圖片描述

復制到這里:

並且自己改成成android gradle的格式,什么是android的格式?

參考這個文件原有的gradle dependencies寫法即可,注意去掉結尾的beta!

build.gradle(Module:app):

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

    compile 'com.squareup.okhttp3:okhttp:3.8.0'
    compile 'org.jetbrains.anko:anko-sdk15:0.9'
    compile 'org.jetbrains.anko:anko-support-v4:0.9'
    compile 'org.jetbrains.anko:anko-appcompat-v7:0.9'

}

點擊sync gradle,把類庫同步到本地

記得要配置Manifest.xml提供網絡訪問的權限!

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.cslg.networktest">

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
......
    </application>
    ........
    <uses-permission android:name="android.permission.INTERNET"	/>
</manifest>

布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cn.cslg.networktest.MainActivity">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/url"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="http://guolin.tech/api/china/16/116"
            />

        <Button
            android:id="@+id/get"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="獲取網絡數據" />

        <ImageView
            android:id="@+id/img"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <ScrollView
            android:id="@+id/scroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="從url獲得的數據"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </ScrollView>

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

布局文件提供了一個EditText,一個TextView,一個Button,一個ImageView,一個ScrollView
EditText:用戶可以輸入任何可以返回字符串或者文件字節的網址
Button:點擊后開始請求
TextView:顯示返回的字符串
ImageView:顯示網址的圖片文件
ScrollView:提供給TextView用,有可能字符串過長溢出,這個控件可以顯示為滾動的文本

kotlin

MainActivity.kt:

package cn.cslg.networktest

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import org.jetbrains.anko.*
import org.jetbrains.anko.custom.async
import java.net.URL

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = find<TextView>(R.id.text)
        val Btn = find<Button>(R.id.get)
        val url = find<EditText>(R.id.url)
        val img = find<ImageView>(R.id.img)

        Btn.onClick({
            val url = url.text.toString()

            async {
                val byteArrayIn = URL(url).readBytes()
                var s = String(byteArrayIn)
                uiThread { text.setText(s) }
            }
        })

    }

}

分析:

可以看到上述代碼引入了anko包,這使得kotlin對布局的獲取和操作更加的簡單直觀

使用 find 的形式直接獲得xml布局中的元素,但仍然使用R.id的形式找到相應id的布局元素

使用 var(可變)或者val(不可變)來聲明並且直接獲得對象的引用,kotlin編譯器將會自動推斷變量類型!

這些find,onClick方法都是anko包提供的

是不是比findViewById和那個xxxListener簡單很多

kotlin還可以用lambada表達式替代原來java看着冗長的匿名類(閉包)

事實上,這里是直接向onClick傳入了一個fun,即函數對象!它將在onClick觸發后去執行

接下來是真正對網絡世界的請求:

URL類是kotlin對java.net庫的擴展,用於網絡請求,構造方法將會生成一個URL對象,里面有倆方法:
參考:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.net.-u-r-l/

使用URL.readText可以直接獲取網站返回的字符串String,一般用於json的獲取

使用URL.readBytes可以將網站返回的內容按字節ByteArray獲取,可用於圖片,文件的獲取

上述使用了Bytes是為了后面獲得一張在線圖片准備,如果想直接獲得json字符串的話,使用readText:

async {
     val s = URL(url).readText()
     uiThread { text.setText(s) }
}

效果

輸入網址,獲得相應數據,此例獲得json

這里寫圖片描述

獲取文件

上面實現的是獲取String,那么獲取文件呢

以圖片文件為例,直接顯示在ImageView控件當中

修改async下的代碼即可

async {
    val data = URL(url).readBytes()
        if (data != null) {
            uiThread {
                val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)// bitmap
                    imageView.setImageBitmap(bitmap)
                    toast("success")
            }
        } else {
            toast("image error")
        }
}

分析:

這次為了獲得文件,必須使用readBytes方法,他會傳回一個ByteArray(字節數組)

然后使用BitmapFactory下的decodeByteArray方法將ByteArray轉換為圖片

效果

試着在EditText輸入圖片的地址:

這里寫圖片描述

轉載請注明出自:http://www.cnblogs.com/devilyouwei/p/6881955.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM