网络相关(下载与请求)

93 阅读2分钟

download下载 方式1.okhttp 方式2.retrofit2

class NetDownLoadUtil {

    /*方式1 okhttp*/

    private val client by lazy { OkHttpClient.Builder().build() }

    private fun createRequest(url: String): Request {
        return Request.Builder().url(url)
            .get()
            .build()
    }

    fun downloadRequest(url: String, targetFile: File, unit: (String) -> Unit) {
        val request = createRequest(url)
        val call = client.newCall(request)
        call.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                unit(e.message ?: "error")
            }

            override fun onResponse(call: Call, response: Response) {
                try {
                    val body = response.body
                    if (body != null) {
                        targetFile.outputStream().use {
                            body.byteStream().copyTo(it)
                        }
                        unit("ok")
                        return
                    }
                } catch (e: Exception) {
                }
                unit("error")
            }
        })
    }

    /*方式2 retrofit2*/
    private fun createRetrofit(): Retrofit {
        return Retrofit.Builder().baseUrl(Url.baseUrl)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .callbackExecutor(Executors.newSingleThreadExecutor()) // 指定回调线程
            .build()
    }

    fun downloadRetrofit(url: String, targetFile: File, unit: (String) -> Unit) {
        createRetrofit().create<TestServiceApi>().requestDownload(url)
            .enqueue(object : retrofit2.Callback<ResponseBody?> {
                override fun onResponse(
                    call: retrofit2.Call<ResponseBody?>, response: retrofit2.Response<ResponseBody?>
                ) {
                    val body = response.body()
                    if (body != null) {
                        /*var input: InputStream? = null
                        var output: FileOutputStream? = null
                        try {
                            val contentLength = body.contentLength()
                            input = body.byteStream()

                            output = FileOutputStream(targetFile)
                            val bytes = ByteArray(2048)
                            var len = 0
                            while (input.read(bytes).also { len = it } != -1) {
                                output.write(bytes, 0, len)
                            }
                            output.flush()
                            unit("200")
                            return
                        }finally {
                            input?.close()
                            output?.close()
                        }*/

                        try {
                            targetFile.outputStream().use {
                                body.byteStream().copyTo(it)
                            }
                            unit("200")
                            return
                        } catch (e: Exception) {
                        }
                    }
                    unit("401")
                }

                override fun onFailure(call: retrofit2.Call<ResponseBody?>, t: Throwable) {
                    unit("500")
                }
            })
    }

}

网络请求

object NetUtil {

    private val client by lazy {
        OkHttpClient.Builder()
            .callTimeout(10 * 1000L, TimeUnit.SECONDS)
            .addInterceptor(MyHeaderInterceptor())
            .addInterceptor(MyLogInterceptor())
            .build()
    }
    private var retrofit: Retrofit? = null

    fun getInstance(): Retrofit {
        if (retrofit == null) {
            retrofit = Retrofit.Builder().client(client)
                .baseUrl(baseUrl)
                .addConverterFactory(ScalarsConverterFactory.create())//使retrofit2支持String泛型
                .addConverterFactory(GsonConverterFactory.create(
                    GsonBuilder().registerTypeAdapter(String::class.java, StringTypeAdapter())
                        .create()
                )
                )
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build()
        }
        return retrofit!!
    }

    inline fun <reified T> createApi(): T {
        return getInstance().create(T::class.java)
    }

    @SuppressLint("CheckResult")
    fun <T> Observable<ResultBean<T>>.dealCallback(callback: RetrofitCallback<T>?) {
        this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({ t ->
            if (t.api_code == 200) {
                callback?.onSuccess(t.data!!)
            } else {
                callback?.onError(t.api_code, t.api_msg)
            }
        }, { err ->
            callback?.onError(500, err.message.toString())
        })
    }

    @SuppressLint("CheckResult")
    fun <T : Any> Observable<T>.dealCallback(ob: Observer<T>) {
        this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(ob)
    }

//    @SuppressLint("CheckResult")
//    fun <T : Any> Observable<T>.dealCallback(callback: RetrofitCallback<T>?) {
//        this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
//            .subscribe(object : Consumer<T> {
//                override fun accept(t: T) {
//                    callback?.onSuccess(t)
//                }
//            }, object : Consumer<Throwable> {
//                override fun accept(t: Throwable) {
//                    callback?.onError(500, t.message.toString())
//                }
//            })
//    }

}

ServiceApi

interface TestServiceApi {
    @GET("api/user/getVipInfo")
    fun requestInfo(): Observable<VipInfoResult>


    @GET("api/user/getVipInfo")
    fun requestInfo2(): Observable<String>

    @GET("api/user/getVipInfo")
    fun requestInfo3(): Observable<ResultBean<VipInfo>>

    @GET
    @Streaming
    fun requestDownload(@Url url: String): Call<ResponseBody?>
}

StringTypeAdapter

/**
 * @author yyf
 * Gson针对String类型的序列化与反序列化规则
 */
class StringTypeAdapter: TypeAdapter<String?>() {
    override fun write(out: JsonWriter?, value: String?) {
        var value = value
        try {
            if (value == null) {
                value = ""
            }
            out?.value(value.toString())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun read(`in`: JsonReader?): String? {
        var value: String?
        try {
            if (`in`?.peek() == JsonToken.NULL) {
                `in`?.nextNull()
                value = ""
                return value
            }
            if (`in`?.peek() == JsonToken.STRING) {
                val str = `in`?.nextString()
                value = str ?: ""
            } else {
                value = `in`?.nextString()
            }
        } catch (e: Exception) {
            value = ""
        }
        return value
    }
}

MyHeaderInterceptor

class MyHeaderInterceptor: Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request().newBuilder()
            .header("Authorization", "df4d1d1a88f507af3c11ec2f8dea478209ccbae39a9659e371cb35f6c931147ee45745ca2fe9ec431104818d62ed623627c1faab26581116ce982ea01bc67a64")
            .header("Accept", "application/json")
            .build()
        return chain.proceed(request)
    }
}

MyLogInterceptor

class MyLogInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()//请求
        val response = chain.proceed(request)//响应
        //请求信息
        Log.d("http", "url=${request.url}。header=${request.headers.get("Authorization")}")
        //响应信息
        val contentType = response.body?.contentType()
        val content = response.body?.string() ?: ""
        Log.d("http", "body=$content")
        return response.newBuilder()
            .body(ResponseBody.create(contentType, content)).build()
    }
}

RetrofitCallback

interface RetrofitCallback<T> {
    fun onSuccess(t:T)
    fun onError(code: Int,msg: String)
}