zoukankan      html  css  js  c++  java
  • 用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

  • 相关阅读:
    延迟加载时发生no session错误的解决办法
    零零散散的一些知识点(一)
    零零散散的一些知识点(二)
    自己写的一个日历表
    js复制网址
    load方法在延迟加载时可能出现的错误。
    JSON基本介绍
    JBOSS4.0 JDBC数据源配置大全
    EJB学习笔记一
    Android程序完全退出的方法
  • 原文地址:https://www.cnblogs.com/devilyouwei/p/6881955.html
Copyright © 2011-2022 走看看