Kotlin入门 + RxAndroid+Retrofit2

Kotlin入门 + RxAndroid+Retrofit2


添加依赖

  1. 在项目目录下build.gradle中添加
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin_version}"
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:${versions.kotlin_version}"
  1. 在app目录下build.gradle中添加
    因为使用到了rxjava+retrofit2的网络框架所以
    apply plugin: 'kotlin-android'
    apply plugin: 'kotlin-android-extensions'

    dependencies {
        implementation 'com.android.support.constraint:constraint-layout:1.0.2'
        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 "org.jetbrains.kotlin:kotlin-stdlib-jre7:${versions.kotlin_version}"
        compile "com.android.support:appcompat-v7:${rootProject.ext.support}"
        testCompile 'junit:junit:4.12'
        compile 'com.android.support.constraint:constraint-layout:1.0.2'

    //    kapt "com.android.databinding:compiler:${versions.databinding}"

        compile "com.squareup.retrofit2:retrofit:${versions.retrofit2}"
        compile "com.squareup.retrofit2:adapter-guava:${versions.retrofit2}"
        compile "com.squareup.retrofit2:converter-gson:${versions.retrofit2}"
        compile "com.squareup.retrofit2:adapter-rxjava:${versions.retrofit2}"
        compile "com.squareup.retrofit2:converter-moshi:${versions.retrofit2}"

        // 大神写的这个库可以支持到rxjava2.X
        //tab 一起使用
        compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

        compile "io.reactivex.rxjava2:rxandroid:${versions.rxandroid}"
    // Because RxAndroid releases are few and far between, it is recommended you also
    // explicitly depend on RxJava's latest version for bug fixes and new features.
        compile "io.reactivex.rxjava2:rxjava:${versions.reactivex}"
    }

页面绑定

做了一个简单的baseActivity,用于绑定页面,简单的管理页面。

    /**
    * Created by guoxw on 2017/5/24.
    * @auther guoxw
    * @date 2017/5/24
    * @desciption
    */
    abstract class BaseActivity : AppCompatActivity() {

        val BTAG: String = BaseActivity::class.java.name

        /**
         * 静态成员
         */
        companion object {
            //管理运行的所有activity
            var mActivities: ArrayList<AppCompatActivity> = ArrayList()
            //单例
            var activity: BaseActivity? = null

        }


        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            requestWindowFeature(Window.FEATURE_NO_TITLE)

            setContentView(getLayoutId())

            initData()
            initView()
            initListener()

            synchronized(mActivities) {
                mActivities.add(this)
            }
        }


        //绑定页面
        abstract fun getLayoutId(): Int

        //初始化页面
        abstract fun initView()

        //初始化data
        abstract fun initData()

        //监听
        abstract fun initListener()

        /**
         * 打开页面
         *
         * @param activity 需要打开的页面
         * @param bundle 传的值
         */
        fun openActivity(activity: Class<*>, bundle: Bundle?) {
            val intent: Intent = Intent()
            if (bundle != null) {
                intent.putExtra("data", bundle)
            }
            intent.setClass(this, activity)
            startActivity(intent)
            overridePendingTransition(R.anim.screen_zoom_in, R.anim.screen_zoom_out)
        }

        /**
         * 关闭所有Activity
         */
        fun finishAll() {
            //复制一份mActivities
            var copy: List<AppCompatActivity> = ArrayList()
            synchronized(mActivities) {
                copy = ArrayList(mActivities)
            }
            //结束所有
           copy.forEach { it.finish() }
            //杀死当前进程
            android.os.Process.killProcess(android.os.Process.myPid())

        }

        /**
         * 关闭所有Activity,除了参数传递的Activity
         *
         */
        fun finishAll(except: AppCompatActivity) {
            var copy: List<AppCompatActivity> = ArrayList()
            synchronized(mActivities) {
                copy = ArrayList(mActivities)
            }

            copy.asSequence()
                    .filter { it !== except }
                    .forEach { it.finish() }
        }

        /**
         * 退出应用
         */
        fun exitApp() {
            finishAll()
            android.os.Process.killProcess(android.os.Process.myPid())
        }

    }

一个简单的Splash页,继承了BaseActivity。打开页面调用的就是baseActivity里的打开页面的方法。
在kotlin中页面绑定十分简单,在xml中定义好控件的id后,在Activity里就能直接使用呢,不用一大堆的findbyId了
而且配合lambda表达式监听事件等变得格外简洁

    import android.os.Handler
    import com.guoxw.gankio.R
    import com.guoxw.gankio.ui.activities.base.BaseActivity
    import kotlinx.android.synthetic.main.activity_splash.*

    class SplashActivity : BaseActivity() {

        var canJump: Boolean = true

        override fun getLayoutId(): Int = R.layout.activity_splash

        override fun initView() {

            img_splash.setImageResource(R.mipmap.haden)


        }

        override fun initData() {

            //延迟两秒跳转到MainActivity
            Handler().postDelayed({
                if (canJump) {
                    openActivity(MainActivity::class.java, null)
                    finish()
                }
            }, 2000)

        }

        override fun initListener() {

            tv_splash_jump.setOnClickListener {
                //主动跳过
                if (canJump) {
                    canJump = false
                    openActivity(MainActivity::class.java, null)
                    finish()
                }
            }

        }

    }

Retrofit2的使用

我这使用的是GankIO的API

定义返回类

没错,你没看错,kotlin类的定义就是那么简单。当然我这里面的泛型使用还是有点问题,kotlin还有in和out的区分,我这没做区分。

    /**
    * Created by guoxw on 2017/5/25.
    * @auther guoxw
    * @date 2017/5/25
    * @desciption
    */
    class GankResponse<T>(val error: Boolean, val results: T) {
        override fun toString(): String {
            return "GankResponse(error=$error, result=$results)"
        }
    }

数据实体类,Parcelable有kotlin的插件,直接生成代码就行了。

    data class GankData(

            //id
            var _id: String,
            //创建时间
            var createAt: String,
            var desc: String,
            var images: Array<String>?,
            var publishedAt: String,
            var source: String,
            var type: String,
            var url: String,
            var used: Boolean,
            var who: String
    ) : Parcelable {
        fun hasImages(): Boolean = images != null

        fun createTime(): String = createAt.substring(0, 10)

        companion object {
            @JvmField val CREATOR: Parcelable.Creator<GankData> = object : Parcelable.Creator<GankData> {
                override fun createFromParcel(source: Parcel): GankData = GankData(source)
                override fun newArray(size: Int): Array<GankData?> = arrayOfNulls(size)
            }
        }

        constructor(source: Parcel) : this(
                source.readString(),
                source.readString(),
                source.readString(),
                source.createStringArray(),
                source.readString(),
                source.readString(),
                source.readString(),
                source.readString(),
                1 == source.readInt(),
                source.readString()
        )

        override fun describeContents() = 0

        override fun writeToParcel(dest: Parcel, flags: Int) {
            dest.writeString(_id)
            dest.writeString(createAt)
            dest.writeString(desc)
            dest.writeStringArray(images)
            dest.writeString(publishedAt)
            dest.writeString(source)
            dest.writeString(type)
            dest.writeString(url)
            dest.writeInt((if (used) 1 else 0))
            dest.writeString(who)
        }

        override fun toString(): String {
            return "GankData(_id='$_id', createAt='$createAt', desc='$desc', images=${Arrays.toString(images)}, publishedAt='$publishedAt', source='$source', type='$type', url='$url', used=$used, who='$who')"
        }
    }

接口定义

  • 方法定义
    /**
    * Created by guoxw on 2017/5/22.
    * @auther guoxw
    * @date 2017/5/22
    * @desciption
    */
    interface GankIOApi {

        /**
         * 分类请求数据
         *
         * @param type
         * 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
         * @param number
         * 请求个数: 数字,大于0
         * @param page
         * 第几页:数字,大于0
         */
        fun getGankIOData(type: String, number: Number, page: Int): Flowable<GankResponse<List<GankData>>>

    }
  • API接口定义
    /**
    * Created by gxw on 17-5-24.
    * @auther gxw
    * @date 17-5-24
    * @desciption
    */
    interface GankIOService {

        /**
         * 分类数据: http://gank.io/api/data/数据类型/请求个数/第几页
         *
         * @param type
         * 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
         * @param number
         * 请求个数: 数字,大于0
         * @param page
         * 第几页:数字,大于0
         *
         * 测试成功
         */
        @GET("data/{type}/{number}/{page}")
        fun getGankIOData(@Path("type") type: String, @Path("number") number: Number, @Path("page") page: Int): Flowable<GankResponse<List<GankData>>>

    }
  • 外部调用方法
    /**
    * Created by gxw on 17-5-24.
    * @auther gxw
    * @date 17-5-24
    * @desciption
    */
    object GankIOResetApi : GankIOApi {

        /**
         * 分类请求数据
         *
         * @param type
         * 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
         * @param number
         * 请求个数: 数字,大于0
         * @param page
         * 第几页:数字,大于0
         */
        override fun getGankIOData(type: String, number: Number, page: Int): Flowable<GankResponse<List<GankData>>>
                = ApiClient.retrofit.create(GankIOService::class.java).getGankIOData(type, number, page)

    }

具体调用

        val gankIOApi: GankIOResetApi = GankIOResetApi

        gankIOApi.getGankIOData("福利", 10, 1)
                .observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
                .subscribe({
                    res ->
                    Log.i("MainActivity", res.toString())
                    if (!res.error) {
                        Log.i("MainActivity", "result size:".plus(res.results.size))
                    } else {

                    }
                }, { e -> Log.e("MainActivity", "error:".plus(e.message)) }, {

                })

        }

有点懒,就先写到这吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值