Android Kotlin(一)—— Kotlin 入门与 HttpURLConnection 网络请求

1024 节日 开启Kotlin学习之旅

一.入门基础

1.环境配置:http://blog.csdn.net/qq_23547831/article/details/52857346

2.基础语法:http://www.runoob.com/kotlin/otlin-android-setup.html

3.Android中的Kotlin程序

 以下代码功能为:点击按钮 然后在TextView中显示值

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)

        var textView = findViewById(R.id.textview) as TextView
        var button = findViewById(R.id.button) as Button
        button.setOnClickListener {
            textView.setText("First Kotlin Code")
        }
    }
}

布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击我吧" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="5dp" />
</LinearLayout>

看起来只是在 点击事件中 比Java少了点代码,但还可以更简洁 如下所示

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_test.*

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        //不使用 findViewById 直接使用ID操作
        button.setOnClickListener {                //点击事件
            textview.text = "First Kotlin Code"    //设置值
        }
    }
}

上述代码 比前面的 代码多了 一行代码,导入了指定的布局文件中所有控件的属性

import kotlinx.android.synthetic.main.activity_test.*

想要实现上述代码 需要在 Module中的 build.gradle中添加插件

apply plugin: 'kotlin-android-extensions'

在前面代码中出现了与Java中不一样的  override 、fun 、var

Java与Kotlin对比:

@Override --> override

default --> public

void --> Unit

fun 函数定义使用关键字

var  可变变量定义

val  不可变变量定义,只能赋值一次的变量(类似Java中final修饰的变量)

二.网络请求

子线程中网络请求 --> Handler Message 通知主线程更新UI  先上完整代码 

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val baseUrl = "https://www.baidu.com/"
        
        button.setOnClickListener {         //点击事件
            HttpThread(baseUrl).start()
        }
    }

    var handler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == 1) {
                textview.text = msg.toString()
            }
        }
    }

//    var handler:Handler = Handler()

    inner class HttpThread : Thread {
        var baseUrl: String = ""

        constructor(baseUrl: String) : super(baseUrl) {
            this.baseUrl = baseUrl    //构造方法传值
        }

        override fun run() {
            super.run()
            var url = URL(baseUrl)
            var httpConnect = url.openConnection() as HttpURLConnection

            httpConnect.connectTimeout = 5 * 1000  // 设置连接超时时间
            httpConnect.readTimeout = 5 * 1000  //设置从主机读取数据超时
            httpConnect.doOutput = true
            httpConnect.doInput = true
            httpConnect.useCaches = false
            httpConnect.requestMethod = "POST" // 设置为Post请求
            httpConnect.connect() // 开始连接

            var inputStream = httpConnect.inputStream
            var reader = BufferedReader(InputStreamReader(inputStream))
//            var str: String = ""
//            while ((str = reader.readLine()) != null) {
//                println(str)
//            }
            var strBuilder = StringBuilder()
            reader.forEachLine {
                strBuilder.append(it)
                Log.e("TAG", it)
            }

            var message = Message.obtain()
            message.obj = strBuilder.toString()
            message.what = 1
            handler.sendMessage(message)

            inputStream.close()
            reader.close()
        }
    }
}

权限: 

<uses-permission android:name="android.permission.INTERNET" />

1.创建网络请求线程类 HttpThread

inner 用于表示内部类的关键字

: 冒号 可用于常量变量的类型声明,函数的返回值,类的继承等等

constructor 修饰次级构造方法

匿名内部类、继承

inner class HttpThread : Thread

声明变量、实例化对象

var baseUrl: String = ""

主构造器

inner class HttpThred(baseUrl: String) : Thread(baseUrl)

次级构造器

constructor(baseUrl: String) : super(baseUrl) {
    this.baseUrl = baseUrl    //构造方法传值
}

2.while的改变

以前在Java中IO流中的读取文本一般如下

但是会报错:Assignments are not expressions, and only expressions are allowed in this context

解决方式借鉴的别人的:https://stackoverflow.com/questions/41537638/assignment-not-allowed-in-while-expression

while在Kotlin中不在支持条件中含有赋值语句

3.Handler方式 更新UI

说下当时遇见的问题

实例化Handler 对象时 无法重写 handleMessage(msg: Message)方法

当时是这样

var handler:Handler = Handler()

改成这样后便能重写方法了

var handler: Handler = object : Handler() {
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        if (msg.what == 1) {
            textview.text = msg.toString()
        }
    }
}

在HttpThread这个内部类中 无法使用到 Activity中的Handler

在定义内部类的时候 加上 inner 声明即可

学习的参考地址

Kotlin中文网:https://www.kotlincn.net/docs/reference/

菜鸟教程:http://www.runoob.com/kotlin/kotlin-tutorial.html

最后效果: 点击按钮、网络请求、TextView显示值


猜你喜欢

转载自blog.csdn.net/ww897532167/article/details/78327588