注意!是Retrofit2+ RxJava2,而不是Retrofit2+ RxJava!
实验目的
- 理解
Restful接口- 学会使用
Retrofit2- 复习使用
RxJava- 学会使用
OkHttp
效果

添加依赖
1 | implementation 'com.android.support:cardview-v7:28.+' |
项目结构

新增一个跳转的ACTIVITY
布局写两个按钮就好了

SwitchActivity.java
1 | public class SwitchActivity extends AppCompatActivity { |
修改AndroidManifest.xml,在SwitchActivity中添加intent-filter,使其成为主界面
(原来这个intent-filter是在MainActivity里)
1 | <activity android:name=".SwitchActivity"> |
获取Github某个用户所有仓库(repository)
新建GithubRepoObj.java

这是用来装HTTP请求的表明用户每个仓库信息的Json数据转换的实体类,已经调用了谷歌的gson库,所以只要注解SerializedName添加正确,可以实现从Json到Class的自动转换
解析的格式通过得到上述访问api链接观察得到
1 | package com.sysu.janking.httpapi.GITHUB; |
新建GitHubService.java
1 | // 不是Class 而是 interface |
这是一个服务接口,用来请求GithubAPI
这里使用了retrofit2的注解方法,将参数user_name放进url,再通过GET请求,返回具体的repository列表,所以被观察者的对象是是一个GithubRepoObj的列表(List)
新建repo_recycler_item.xml
这是显示仓库列表的RecyclerView单项布局
1 |
|
新建GithubRepoRecyclerAdapter.java
用来正确显示用户仓库的列表(RecyclerViewList)
1 | package com.sysu.janking.httpapi.GITHUB; |
这里有几个容易出错的地方
第一点
给列表中添加了数据之后要通知改变UI
调用的是这个
notifyItemInserted(repos.size() - 1);
也就是增加的用户的下标(ArrayList理解为数组的话)
第二点
reset方法清空列表的时候,也要记得通知改变UI
notifyItemRangeRemoved(0,count);
第三点
getOpen_issues_count()方法返回的是int值,表示的是该仓库开放的问题数
如果直接向下面这样调用会出错,因为如果setText的参数是int值,它会当做是资源号,也就是像mipmap,layout等文件夹里放的资源一样,但是一般不会找到这个int值对应的资源,所以应用会崩溃!
1 | holder.repo_issues_count.setText(repos.get(position).getOpen_issues_count()); |
所以如果要让TextView或者EditText显示数字的时候,应该要转换成String,如下
1 | holder.repo_issues_count.setText(String.valueOf(repos.get(position).getOpen_issues_count())); |
因此,对RecyclerView进行数据修改的时候,要记得修改存储数据的容器,更要记得通知UI的改变!
新建RepoActivity
布局activity_repo.xml

1 |
|
代码RepoActivity.java
1 | package com.sysu.janking.httpapi.GITHUB; |
注意这里使用的是RxJava2的版本,很多教程都是1.1.0,这两个版本区别很大!
比如RxJava的观察者是Subscriber,但是RxJava2的观察者是DisposableObserver
而且Retrofit调用RxJava的时候用的工厂也不一样
下面是正确的调用方式
1 | retrofit.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) |
就是这个RxJava2CallAdapterFactory困扰了我好久
之前是一直提示这个错误
1
2 > java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Observable<java.util.List<com.sysu.janking.httpapi.GithubRepoObj>> for method GitHubService.getRepo
>
更多可以查看RxJava2的介绍
获取Github某个用户某个仓库(repository)的所有问题(issue)
新建GithubIssueObj.java
1 | package com.sysu.janking.httpapi.GITHUB; |
修改GitHubService.java
添加一个GET请求的方法
返回的是某个用户某个仓库所有Issue的集合,参数是Github用户名和仓库名
1 | ("/repos/{user_name}/{repo}/issues") |
新建issue_recycler_item.xml
这是显示问题(Issue)的RecyclerView的单项布局
1 |
|
新建GithubIssueRecyclerAdapter.java
1 | package com.sysu.janking.httpapi.GITHUB; |
新建IssuesActivity
布局activity_issues.xml

1 |
|
代码IssuesActivity.java
1 | package com.sysu.janking.httpapi.GITHUB; |
这里的方法getGithubIssues同样也是使用Rxjava2来异步请求仓库的所有问题
对Github某个仓库(repository)添加问题(issue)
API原型
接口:https://api.github.com/repos/{用户名}/{仓库名}/issues
方法:POST
提交内容:
1 | { |
添加提交数据的类GithubIssueJsonObj
1 | public class GithubIssueJsonObj { |
这个类很简单,但是作用却不小,因为POST需要提交一个Json的数据,所以需要通过这个方法把实体类传输过去,应该可以自动解析出来
修改GitHubService.java
添加一个POST请求的方法
1 | ("Authorization: token {YOUR_TOKEN}")//需要补充TOKEN |
因为GitHub上发表问题需要登录,所以需要验证身份
但是在这种简单的网络请求中不会通过输入用户名和密码来验证身份(不安全是其中一个原因)
GitHub采用了更加安全同时也很简便的办法验证,就是通过授权Token
新建GithubPostIssueObj.java
POST方式提交数据之后也会有返回的数据,但是我们不需要利用这个数据,所以我就随便写了个类,随便写了个成员,对结果不会进行分析,只是为了让Retrofit正常运行而已
因为对于不保留结果不知道怎么处理,肯定会有更好的方法处理这种情况
1 | package com.sysu.janking.httpapi.GITHUB; |
获取GitHub的Token
在已经登录GitHub的账户上点击Setting

点击Developer Setting

点击Personal access tokens,并点击Generate new token

应该只要允许repo权限就好了(不然权限太大很危险)

点击确认之后应该就会返回Token列表显示具体的token值
token值只会显示一次,所以得及时复制保存,忘了的话,点击上图中的Regenerate token就好了

然后把这个token填写到GitHubService里面的token项中
补充postGithubIssue方法
其实跟获取仓库的问题差不多,只不过GitHubService调用的方法不一样而已
方法中提交的数据是new GithubIssueJsonObj(title, body)
而且需要注意的是,提交成功后会在onNext中再次调用getGithubIssues更新问题(Issue)列表
1 | public void postGithubIssue(String title, String body){ |
参考链接
RxJava2的介绍
Rxjava2和Retrofit的适配
Retrofit之请求参数
HTTP请求方法中,如Get/Post方式中的HTTP头 Authorization 怎么添加?
