Retrofit2+RxJava2实现一个网络请求框架精简封装

今天讲下如何使用Retrofit2+RxJava2实现一个网络请求框架的步骤:
前提准备条件自然要有清单文件别忘记添加网络请求权限:

 

然后开始真正的代码集成实现步骤:
第一步:首先在build.gradle文件中添加以下依赖:

dependencies {
	implementation 'com.squareup.okhttp3:okhttp:3.2.0'
	implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    }

第二步:在application中初始化Retrofit

class MyApp : Application() {

 override fun onCreate() {
        super.onCreate()
        app = this
        //初始化OkHttp
        okHttpInstance()
        //初始化Retrofit
        RetrofitInstance()
      
    }


//初始化okhttp    Retrofit
    companion object {

        lateinit var app: MyApp

        var mOkHttpClient: OkHttpClient? = null
        var mRetrofit: Retrofit? = null

        fun okHttpInstance(): OkHttpClient {
            var logInterceptor = HttpLoggingInterceptor((HttpLoggingInterceptor.Logger { message ->
                Log.e("message", message)

            }))
            logInterceptor.level = HttpLoggingInterceptor.Level.BODY


            mOkHttpClient = OkHttpClient().newBuilder()
                    .addNetworkInterceptor(logInterceptor)
                    .build()
            return mOkHttpClient!!
        }


        fun RetrofitInstance(): Retrofit {
            mRetrofit = Retrofit.Builder()
                    .baseUrl(UrlConfig.BASE_URL)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(mOkHttpClient)
                    .build()

            return mRetrofit!!
        }
    }



}

第三步:建立你的配置全局网络请求Url工具类UrlConfig.kt

class UrlConfig {
    companion object {
        //正式服务器url
        val BASE_URL = "http://mingshiapp.com"
    }

}

第四步:创建你的请求主体类IPServer.kt:

/**
 * @Description:配置网络请求主体业务接口
 * @Author: junjiew
 * @Time:   2018/7/03 14:47
 */
interface IPServer {

	//网络请求测试
    @GET("/test")
    fun getTestData():Observable

}

第五步:在activity中调用关键代码实现:

var bean : TestData? = null

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
       //调用网络请求方法
       initData()
      
    }

//调用网络框架请求
private fun initDatas() {
      var server = MyApp.RetrofitInstance().create(IPServer::class.java)
            server.getTestData()
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({ result ->
                        bean = result as TestData
                        LogUtils.d(TAG,"result:"+result.toString())
                    }, { error ->

                        //Request FAIL
                        LogUtils.d(TAG,"error:"+error.toString())
                    })
        

    }

到这里Retrofit2+RxJava2实现一个网络请求框架就已经集成完毕了,是不是很简单看起来,哈哈,兄弟,不要大意,开发最可怕的就是你把一个东西看简单了,然后真正实现的时候遇到一个坑自己半天爬不出来,这是个老搬砖的一路走过来的经验啊!哈哈

下面再补充一个用retrofit进行文件下载的实现方法:

/**
 * Retrofit 网络请求接口封装
 */
interface IPServer {
 // option 2: using a dynamic URL
    //如果你在下载一个大的文件,Retrofit默认会将整个文件移到内存中,为了避免这种情况,我们需要为这种请求加一个特殊的注解:
    // @Streaming 加入这个 @Streaming 声明后并不是将整个文件全部放入内存中,
    // 而是实时的返回字节码。值得注意的是,如果你在添加了 @Streaming声明的情况下依然使用上面的方式来进行下载,Android就会抛出一个溢出
    // android.os.NetworkOnMainThreadException。
    //所以,最后一步就是把请求包装到一个另外的线程中,比如使用 AsyncTask

    @Streaming
    @GET
    fun downloadFileWithDynamicUrlSync(@Url fileUrl: String): Call


}

代码调用部分:

private fun downLoadFile(url: String, fileName: String) {


        var service = MyAPP.Companion.initRetrofitInstance().create(IPServer::class.java)


        object : AsyncTask() {
            override fun doInBackground(vararg p0: Void?): String {
                var futureStudioIconFile: File? = null
                var call: Call = service.downloadFileWithDynamicUrlSync(url)
                call.enqueue(object : Callback {

                    override fun onResponse(call: Call?, response: Response?) {
                        if (response!!.isSuccessful) {
                            LogUtils.d(TAG, "server contacted and has file")
                            try {
                                //系统相册目录,这里的目录你可以根据你的需要修改,我这里下载的文件类型是图片,所以保存到了系统相册目录
                                futureStudioIconFile = File(Environment.getExternalStorageDirectory().toString() + File.separator + Environment.DIRECTORY_DCIM
                                        + File.separator + "Camera" + File.separator + fileName)

                                if (!(futureStudioIconFile?.parentFile?.parentFile?.exists())!!) {
                                    LogUtils.d(TAG, "futureStudioIconFile?.parentFile 存在")
                                    futureStudioIconFile?.parentFile?.parentFile?.mkdirs()

                                    if (!futureStudioIconFile?.parentFile?.exists()!!) {
                                        futureStudioIconFile?.parentFile?.mkdirs()

                                        if (!(futureStudioIconFile?.exists())!!) {
                                            futureStudioIconFile?.createNewFile()
                                        } else {
                                            LogUtils.d(TAG, "futureStudioIconFile 存在2222")

                                        }

                                    } else {
                                        LogUtils.d(TAG, "futureStudioIconFile?.parentFile?.mkdir() 不成功")
                                    }
                                } else {
                                    LogUtils.d(TAG, "futureStudioIconFile?.parentFile 存在")

                                }

                                var writtenToDisk = writeResponseBodyToDisk(response.body()!!, futureStudioIconFile!!)
                                LogUtils.d(TAG, "file download was a success?-------> $writtenToDisk" + "文件路径是:" + futureStudioIconFile!!.absoluteFile)
                                if (writtenToDisk) {
                                    //通知相册更新 ,如果没有保存到相册就不用这部操作了
                                    var intent: Intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
                                    var uri: Uri = Uri.fromFile(futureStudioIconFile)
                                    intent.data = uri
                                    activity?.sendBroadcast(intent)
                                    // 如果下载成功,做提示下载成功的操作
                                    Toast.makeText(activity, "download success", Toast.LENGTH_SHORT).show()
                                } else {
                                    Toast.makeText(activity, "download faile", Toast.LENGTH_SHORT).show()
                                }


                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                        } else {
                            LogUtils.d(TAG, "server contact failed")
                        }
                    }

                    override fun onFailure(call: Call?, t: Throwable?) {
                        LogUtils.d(TAG, "error")
                    }
                })
                return "sss"
            }

        }.execute()

    }

你可能感兴趣的:(android)