Retrofit+Rxjava-以自己的方式重头开始-入门篇

之前小萌新直接上项目,然后立马就用上了Rretrofit和Rxjava来做,没有特别去学习,然后直接就干了。看了看别人的用法。 后面也根据个人请求数据结果进行了封装,总共封装了两两次,基本实现了通用请求,一个请求方法就搞定所有请求,返回不同的对象或者对象列表

MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-初步封装-相关关键类

MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-二次封装-下载上传/类型转换完善

MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-再次封装-利用泛型搞定不同对象解析

以上就是之前做项目关于Retrofit/Rxjava的学习,上去就干了,没有看太多,这样确实不太好!还是该补补知识妮...于是乎,我们从官方案例开始,小萌新是从一个B站的国外的教学视频开始的,那个帅哥老外基本把官方案例全部都实践教学了一遍,同时也是进行了扩展教学!

开始前准备!

https://www.bilibili.com/video/av47872658 - 时间不长,一上午基本就可以看完,加油,么么哒!

官方【看官方比较锻炼记几个,I think】文档还是得有: Retrofit - 里面基本使用方法 GitHub地址: square/retrofit

小萌新是Kotlin工程做的实践工程,基本知识时间长了不用,容易遗忘,而且再不是很熟练的情况下和其他语言来回切换容易混淆,所以需要补补Kotlin 基础语法 | 菜鸟教程

另外测试接口可以在线测试(其他工具也可以,像postman这些) 在线HTTP接口测试工具 - Getman ,比如官方的是github获取用户开源项目列表的请求接口,为了看返回的列表结构,我们可以提前看下返回结构!如下:

image

准备差不多了,可以开始来搞起了!

看下官方的初步创建和使用:

image

其中关于@Path,我用的确实少,主要是接口一般都很少中间需要动态参数的,不过有必要了解!

一、下面是关于get/post请求相关参数介绍

**@Path **用来将参数拼接到请求url中

**@Header **用来添加信息到请求头 - 官方还说了Headers that need to be added to every request can be specified using anOkHttp interceptor. 如果需要每个请求都添加,那请求再OkHttp的拦截器里面统一处理.

image
image
image
image

二、了解以上知识后,我们就可以开始实践之路了

添加依赖哟build.gradle

 implementation 'com.squareup.retrofit2:retrofit:2.6.0'
 implementation 'com.squareup.retrofit2:converter-gson:2.6.0'

**Repo.kt **- 根据前面在线测试接口返回数据(取几个字段来创建实体类就好)

package com.hl.rxnettest

class Repo{
    var id: Long = -1
    public var name: String? = null
    var full_name: String? = null
    // class owner - not need
    var html_url: String? = null
    var description: String? = null
}

ToStringConverterFactory.java - 字符串结构类型返回转换器 - 这里java也可以喲

package com.hl.rxnettest;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public class ToStringConverterFactory  extends Converter.Factory {
    private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");

    @Override
    public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (String.class.equals(type)) {
            return new Converter() {
                @Override
                public String convert(ResponseBody value) throws IOException {
                    return value.string();
                }
            };
        }
        return null;
    }

    @Override public Converter requestBodyConverter(Type type, Annotation[] parameterAnnotations,
                                                                    Annotation[] methodAnnotations, Retrofit retrofit) {
        if (String.class.equals(type)) {
            return new Converter() {
                @Override
                public RequestBody convert(String value) throws IOException {
                    return RequestBody.create(MEDIA_TYPE, value);
                }
            };
        }
        return null;
    }
}

GitHubService.kt - 定义请求服务接口【定义了三种不同类型的返回结果】

package com.hl.rxnettest

import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path

interface GitHubService {
    // 无需添加解析器- 返回原始ResponseBody
    @GET("users/{user}/repos")
    fun listReposResponseBody(@Path("user") user: String): Call

    // 添加ToStringConverterFactory解析器 - 返回字符串结果【本质:ResponseBody value -> value.string()】
    @GET("users/{user}/repos")
    fun listReposString(@Path("user") user: String): Call

    // 添加GsonConverterFactory解析器 - 返回Json解析的对象列表
    @GET("users/{user}/repos")
    fun listRepos(@Path("user") user: String): Call>
}

MainActivity.kt - 三种不同的请求方式调用

package com.hl.rxnettest

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.ResponseBody
import retrofit2.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Example of a call to a native method
        sample_text.text = stringFromJNI()

        // Retrofit使用学习
        // 创建Retrofit请求对象
        var retrofit: Retrofit = Retrofit.Builder()
                // 设置数据解析器`
                // 无需解析 -> 方式0
                // Json解析 -> 方式1
                // .addConverterFactory(GsonConverterFactory.create())
                // 字符串解析 -> 方式2
                // .addConverterFactory(ToStringConverterFactory())
                // 设置网络请求地址
                .baseUrl("https://api.github.com/")
                .build()
        // 创建GitHubService请求服务
        // person::class 和Person::class都是获取kotlin的KClass -> 先获取到kotlin的KClass然后再获取javaClass
        // 说明: https://blog.csdn.net/fly7632785/article/details/79863049
        var gitHubService = retrofit.create(GitHubService::class.java)

        // UI线程中同步执行错误提示 - Caused by: android.os.NetworkOnMainThreadException
        // var repos = gitHubService.listRepos("FanChael")
        // var response = repos.execute()

        // 方式0: 创建网络请求接口实例 - 返回ResponseBody结果,response.body()?.string()自己进行解析
        var reposResponseBody = gitHubService.listReposResponseBody("FanChael")
        reposResponseBody.enqueue(object : Callback{ // object的作用是调用内部匿名类
            override fun onResponse(call: Call, response: Response){
                // Returns true if the code is in [200..300)
                if (response.isSuccessful) {
                    // response.body() -> ResponseBody
                    Log.e("reposResponseBody-s", response.body()?.string())
                } else {
                    Log.e("reposResponseBody-s-f", "请求错误了!")
                }
            }
            override fun onFailure(call: Call, t: Throwable){
                Log.e("reposResponseBody-f", t.message)
            }
        })

        /*
        // 方式1: 创建网络请求接口实例 - 返回字符串结果
        var reposString = gitHubService.listReposString("FanChael")
        reposString.enqueue(object : Callback{ // object的作用是调用内部匿名类
            override fun onResponse(call: Call, response: Response){
                if (response.isSuccessful) {
                    // response.body() -> String
                    Log.e("reposString-onResponse", response.body())
                } else {
                    Log.e("reposString-onResponse", "请求错误了!")
                }
            }
            override fun onFailure(call: Call, t: Throwable){
                Log.e("reposString-onFailure", t.message)
            }
        })*/

        /*
        // 方式2: 创建网络请求接口实例 - Gson解析后返回对象列表
        var repos = gitHubService.listRepos("FanChael")
        // 发起请求,UI线程需要异步请求
        repos.enqueue(object : Callback>{ // object的作用是调用内部匿名类
            override fun onResponse(call: Call>, response: Response>){
                if (response.isSuccessful) {
                    // response.body() -> List
                    Log.e("repos-onResponse", response.body()?.get(0)?.name)
                } else {
                    Log.e("repos-onResponse", "请求错误了!")
                }
            }
            override fun onFailure(call: Call>, t: Throwable){
                Log.e("repos-onFailure", t.message)
            }
        })*/
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    companion object {

        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("native-lib")
        }
    }
}

以上可以分别打开/注释来测试不同的方式(方式1和2请设置对应的转换器,同时设置,最后一次设置有效!)

**二.1 **关于Kotlin类的class获取的方式 retrofit.create(GitHubService::class.java),如下 https://blog.csdn.net/fly7632785/article/details/79863049 :

image

**二.2 **其中ToStringConverterFactory这个转换器,主要做了如下工作:

image

其实就是获取了ResponseBody的string()字符串,所以其实我们也可以直接采用方式0,返回ResponseBody的结果,然后获取:

image

当然我们定义一个转换器,看起来更清晰,也更方便了呀!后面可以看下FastJson转换器的源码,应该就更清晰了呀啦!

差不多今天就是这样搞了搞,算是入门了吧,小皮球....那个视频里面讲了一些Okhttp日志的拦截,然后大部分都是讲了请求参数的处理(什么header, 什么认证呀,什么token呀,还要就是添加拦截器等),下一篇,我们争取过一遍那些案例,实践实践!

到这里,本来想着结束,一想,小萌新觉得有必要贴下结束:

  Retrofit其实我们可以理解为OkHttp的加强版,它也是一个网络加载框架。底层是使用OKHttp封装的。准确来说,网络请求的工作本质上是OkHttp完成,
而 Retrofit 仅负责网络请求接口的封装。它的一个特点是包含了特别多注解,方便简化你的代码量。并且还支持很多的开源库(著名例子:Retrofit + RxJava)。
都是square公司的。还有https://github.com/AndroidKnife/RxBus,基于rxjava搞的.. Rx家族目前来看还不错...

 OkHttp是核心

另外就是API在线文档:

Retrofit 2.3.0 API​square.github.io

不会了,就慢慢来,但是自己不要老是堕落,玩耍,浪费时间,说的就是我!哼!

打算自己学习造个轮子...

https://github.com/FanChael/RxNet

你可能感兴趣的:(Retrofit+Rxjava-以自己的方式重头开始-入门篇)