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)
}