Android-1 Kotlin Volley

开发Android也有些时间了,一直想把一些基础的组件和功能封装起来,做成一个简单的android开发框架,以备以后的使用和开发,今天就把之前的一些代码整理出来,当然了,也有很多代码是参考了网上的,这里我就不一一鸣谢了。

网络请求是所有App中必须要实现的,从最开始的HttpUrlConnection,到HttpClient,再到Volley,以至于Retrofit,当然了,还有很多http库,可以说选择众多,也各有所长;这里主要是介绍Google的开源框架Volley,以前对它的一些封装。

开发语言:Kotlin
开源框架:Volley EventBus Anko Okhttp Fastjson

Volley封装

VolleyExtensions.kt

  
package com.vslimit.kotlindemo.util.net.volley

import android.content.res.Resources
import com.android.volley.*
import com.vslimit.kotlindemo.R

fun VolleyError.toString(res: Resources): String {
    when {
        isApiError() -> return getApiErrorMessage(res)
        isNetworkError() -> return res.getString(R.string.no_data_connection)
        this is TimeoutError -> return res.getString(R.string.generic_server_down)
        else -> return res.getString(R.string.generic_error)
    }
}

private fun VolleyError.isNetworkError() = this is NetworkError || this is NoConnectionError

private fun VolleyError.isApiError() = this is ServerError || this is AuthFailureError

/** @return A user readable message that interprets the cause of the Api failure. */
private fun VolleyError.getApiErrorMessage(res: Resources): String {

    if (networkResponse != null) {
        when (networkResponse.statusCode) {
            404 -> return res.getString(R.string.no_results_found)
            422, 401, 411, 417 -> {
                return res.getString(R.string.generic_error)
            }
            else -> return res.getString(R.string.generic_server_down)
        }
    }
    return res.getString(R.string.generic_error)
}


inline fun <reified T : Any> RequestQueue.add(listener: Listener<T>?,
                                              url: String,
                                              noinline configure: ((Request<*>) -> Any)? = null,
                                              method: Int = Request.Method.GET) {

    val volleyListener = Response.Listener<T> { r -> listener?.onCompleted(null, r) }
    val errorListener = Response.ErrorListener { e -> listener?.onCompleted(e, null) }
    val request = FastJsonRequest(method, url, T::class.java, volleyListener, errorListener)
    configure?.invoke(request)
    this.add(request)
}

inline fun <reified T : Any> RequestQueue.post(listener: Listener<T>?,
                                               url: String,
                                               noinline configure: ((Request<*>) -> Any)? = null,
                                               param: MutableMap<String, String> = hashMapOf()) {

    val volleyListener = Response.Listener<T> { r -> listener?.onCompleted(null, r) }
    val errorListener = Response.ErrorListener { e -> listener?.onCompleted(e, null) }
    val request = NormalPostRequest(url, T::class.java, volleyListener, errorListener, param)
    configure?.invoke(request)
    this.add(request)
}    

NormalPostRequest

package com.vslimit.kotlindemo.util.net.volley

import android.util.Log
import com.alibaba.fastjson.JSON
import com.android.volley.*
import com.android.volley.Response.Listener
import com.android.volley.toolbox.HttpHeaderParser
import org.json.JSONException
import java.io.UnsupportedEncodingException

/**
 * Created by vslimit on 16/5/26.
 */
class NormalPostRequest<T>(url: String, private val clazz: Class<T>, private val mListener: Listener<T>, errorListener: Response.ErrorListener, private val mMap: Map<String, String>) : Request<T>(Method.POST, url, errorListener) {

    //mMap是已经按照前面的方式,设置了参数的实例
    @Throws(AuthFailureError::class)
    override fun getParams(): Map<String, String> {
        return mMap
    }

    //此处因为response返回值需要json数据,和JsonObjectRequest类一样即可
    override fun parseNetworkResponse(response: NetworkResponse): Response<T> {
        try {
            val jsonString = String(response.data)
            Log.d("return json:::", jsonString)
            return Response.success(JSON.parseObject(jsonString, clazz), HttpHeaderParser.parseCacheHeaders(response))
        } catch (e: UnsupportedEncodingException) {
            return Response.error<T>(ParseError(e))
        } catch (je: JSONException) {
            return Response.error<T>(ParseError(je))
        }
    }

    override fun deliverResponse(response: T) {
        mListener.onResponse(response)
    }

}

FastJsonRequest

package com.vslimit.kotlindemo.util.net.volley

import android.util.Log
import com.alibaba.fastjson.JSON
import com.android.volley.*
import com.android.volley.Response.*
import com.android.volley.toolbox.HttpHeaderParser
import com.android.volley.Response.Listener

/**
 * Created by vslimit on 16/1/19.
 */
open class FastJsonRequest<T> : Request<T> {

    private val clazz: Class<T>
    private val headerz: MutableMap<String, String> by lazy { hashMapOf("Accept" to "application/json") }
    private val listener: Listener<T>

    private var param: MutableMap<String, String> = hashMapOf()

    constructor(url: String, clazz: Class<T>, listener: Listener<T>, errorListener: ErrorListener) :
    super(Method.GET, url, errorListener) {
        this.clazz = clazz
        this.listener = listener
    }

    constructor(method: Int, url: String, clazz: Class<T>, listener: Listener<T>, errorListener: ErrorListener) :
    super(method, url, errorListener) {
        this.clazz = clazz
        this.listener = listener
    }

    constructor(method: Int, url: String, clazz: Class<T>, listener: Listener<T>, errorListener: ErrorListener, param: MutableMap<String, String>) :
    super(method, url, errorListener) {
        this.clazz = clazz
        this.listener = listener
        this.param = param
    }

    @Throws(AuthFailureError::class)
    override fun getHeaders(): Map<String, String> = headerz

    @Throws(AuthFailureError::class)
    override fun getParams(): Map<String, String> = param


    override fun deliverResponse(response: T) = listener.onResponse(response)

    override fun parseNetworkResponse(response: NetworkResponse?): Response<T>? {
        try {
            val json = String(response!!.data)
            Log.d("return json:::", json)
            return success(JSON.parseObject(json, clazz), HttpHeaderParser.parseCacheHeaders(response))
        } catch(e: Exception) {
            return error<T>(ParseError(e))
        }
    }
}

在App中使用OKHttp处理Volley底层请求
App


package com.vslimit.kotlindemo

import android.app.Application
import android.content.Context
import android.support.multidex.MultiDex
import com.android.volley.RequestQueue
import com.android.volley.toolbox.HurlStack
import com.android.volley.toolbox.Volley
import com.squareup.okhttp.OkHttpClient
import com.squareup.okhttp.OkUrlFactory
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
import kotlin.properties.Delegates

class App : Application() {

    companion object {
        var instance: App by Delegates.notNull()
        var queue: RequestQueue? = null
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
        queue = initQueue()
    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }

    fun initQueue(): RequestQueue {
        val factory = OkUrlFactory(OkHttpClient())
        val hurlStack = object : HurlStack() {
            @Throws(IOException::class) override fun createConnection(url: URL): HttpURLConnection {
                return factory.open(url)
            }
        }
        return Volley.newRequestQueue(this, hurlStack)
    }
}

项目中使用

fun init() {
        if (NetworkUtil.isNetwork(act)) {
            val listener = Listener<IPResult> { e, r ->
                e?.let { Bus.post(BaseEvent<IPResult>(error = e)) }
                r?.let { Bus.post(BaseEvent(response = r)) }
            }
            val url = "http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42"
            Log.d("Url:::", "")
            App.queue!!.add(listener, url)
            //post 调用
            //App.queue!!.post(listener, url, hashMapOf("aaa" to "aaa", "bbb" to "bbb"))
            toast("正在加载中...")
        } else {
            alert("网络错误", "网络未连接,请检查网络")
        }
    }

    fun onEventMainThread(event: BaseEvent<IPResult>) {
        val error = event.error
        result = event.response
        info(result)
        toast("加载完成!!!")
        if (error != null) {
            toast(error.toString(resources))
        } else {
            if (result!!.code == Result.SUCCESS) {
                async() {
                    uiThread {
                        resultTv.text = result!!.data!!.country
                    }
                }
            } else {
                toast(result!!.code)
            }
        }
    }

至此,完成了对Volley封装,项目中直接使用即可。

更多代码详见:https://github.com/vslimit/kotlindemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容