前言:
笔记记录从现在开始,每天记录一点自己的问题和想法。保证自己一直处于学习中。
最近一直在开发Android,真的是给自己写吐了。但是也真正发现自己有多落后,以前在学习开发的东西,一直觉得自己用的东西很高级了,但是真正接触到实际项目中的Android草明白自己缺的不是一点点。所以从今天开始,笔记记录,希望养成习惯,提示自己的无知。
笔记:
年前一直开发的app,我基本从头研究了下公司的app,采用的
M-V-VM架构,Model是使用Retrofit2封装的网络请求的框架,以前只知道HTTPConnectiong,okhttp已经是很高级的,但是Retrofit2刷新了我的观念。这次笔记就记录下这个M吧。
以前使用了okhttp就完全抛弃了HTTPConnetion,现在使用了Retrofit2,是时候抛弃OKhttp(非完全抛弃)
总结部分
先挂官网https://square.github.io/retrofit/
1.Retrofit2是基于okhttp的,所以不要完全抛弃啊
2.以前Android写请求都是每个请求都是直接写,使用了Reetrofit2,需要把接口定义在统一的接口中。如下:
public interface Api {
@GET("/getStudent")
MvcResult getStudents(String id);
}
- MvcResult 接口的返回类型,表示请求返回的类型(建议统一返回结果)
- @GET(请求路径) 请求类型和请求路径
请求类型:根据RESTFul GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,HTTP
请求路径:这里忽略不要写http://ip:端口, 直接写后面的路径 - 请求参数:直接写参数类型,参数名即可(post请求需要加上注解)
public interface Api {
@FormUrlEncode
@POST("/getStudent")
MvcResult getStudents(@Field String id);
}
一些常用注解
-
@Headers
设置请求头–(重复的不会覆盖) -
@FormUrlEncode
表示请求的实体是一个form表单,每个键值对需要使用@Field标记 -
@Body
标记参数是一个对象–不可与FormUrlEncode一起使用,会报错 -
@Field
表单提交,与 FieldMap、FormUrlEncoded注解 配合使用。 -
@FieldMap
相当于多个Field的集合,接受 Map<String, String> 类型,非 String 类型会调用 toString() 方法。 -
@Part
表示多部分中某个部分-- 适合用于文件上传–添加非文件的参数-
a. 如果类型是MultipartBody.Part,则内容将直接使用。 忽略注释中的名称(即@Part MultipartBody.Part部分);
-
b. 如果类型是RequestBody,则该值将直接与其内容类型一起使用。 在注释中提供零件名称(例如@Part(“body”)RequestBody body);
-
c. 其他对象类型将通过使用转换器转换为适当的表示形式。 在注释中提供零件名称(例如,@Part(“student”)Student student);值可以是null,它将从请求主体中被省略。
-
-
@PartMap
相当于多个Part的集合,默认接受 Map<String, RequestBody> 类型,非 RequestBody 会通过 Converter 转换。
-
@Path
相当于@PathVariable,将参数拼接到url后面 -
@Query和@QueryMap
将数据转换成“键=值”的形式,并且添加到URL的结尾。例如,类似qs的作用 -
@Url
动态指定Path路径。
来一波完整流程调用
1.定义网络请求接口
public interface Api{
@FormUrlEncode
@POST("/api/login")
Observabel<MvcResult> login(@Field("token") String token);
@GET("/api/login")
Observable<MvcResult> getInfo(String id);
}
2.创建方法调用接口
public interface DataSource{
Observable<MvcResult> login(String token);
Observable<MvcResult> getInfo(String id);
}
3.创建接口实现类
public class DataSourceImpl implements DataSource {
private Api api;
private volatile static DataSourceImpl INSTANCE = null;
public static DataSourceImpl getInstance(Api api) {
if (INSTANCE == null) {
synchronized (DataSourceImpl .class) {
if (INSTANCE == null) {
INSTANCE = new DataSourceImpl (apiService);
}
}
}
return INSTANCE;
}
public static void destroyInstance() {
INSTANCE = null;
}
private HttpDataSourceImpl(Api api) {
this.api= api;
}
@Override
public Observable<MvcResult> login(String token) {
return api.login(token);
}
@Override
public Observable<MvcResult> getInfo(String id) {
return api.getInfo(id);
}
4.创建全局统一的数据仓库–即MVVM 中的真正的M(Model)
public class Repository extends BaseModel implements DataSource{
private volatile static Repository INSTANCE = null;
private final DataSource dataSource;
private Repository (@NonNull DataSource httpDataSource) {
this.dataSource = httpDataSource;
}
public static Repository getInstance(DataSource dataSource) {
if (INSTANCE == null) {
synchronized (Repository.class) {
if (INSTANCE == null) {
INSTANCE = new Repository (dataSource);
}
}
}
return INSTANCE;
}
@VisibleForTesting
public static void destroyInstance() {
INSTANCE = null;
}
@Override
public Observable<MvcResult> login(String token) {
return dataSource.login(token);
}
@Override
public Observable<MvcResult> login(String id) {
return dataSource.getInfo(id);
}
}
到这Model层就结束了,接下来的Activity,ViewModel 中直接调用仓库中的方法即可。下阶段记录MVVM 中的V