注意!是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 怎么添加?