Retrofit 与 annotation Processor ,EventBus结合使用的一个简单示例
代码地址:https://github.com/baofei/RetrofitAnnotation
用annotation processor 把Retrofit的接口生成Manager,网络请求成功的数据将会使用EventBus post出去
简单介绍下(Annotation Processing ),在Java中有一个apt的命令行工具(也包含了javac命令的功能,即编译功能),它的作用是在编译源文件(.java)之前,通过一个自定义的注解处理器(AnnotationProcessor)解释并处理源文件中的注解,由注解处理器生成一些新的源文件,字节码文件(.class),或其他的文本文件,APT也会对新生成源文件进行编译,直到没有新的文件生成。具体的Google下就有了。
APT需要实现AbstractProcessor,可以看看大神们写的文章。
部分代码
RetrofitManager , 实现Retrofit的单例
<pre>public class RetrofitManager {
public static RetrofitManager mManager = new RetrofitManager();
public static OkHttpClient mClient;
private Retrofit retrofit;
public String mBaseUrl;
public HashMap<String, String> mHeader;
private int mRetrofitCode;
private Context mContext;
private RetrofitManager() {
}
public static RetrofitManager getInstance() {
return mManager;
}
public void init(Context context, String url) {
mBaseUrl = url;
mClient = createClient();
mContext = context.getApplicationContext();
createRetrofit();
}
private OkHttpClient createClient() {
return new OkHttpClient.Builder().build();
}
private void createRetrofit() {
retrofit = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(mClient)
.build();
mRetrofitCode = retrofit.hashCode();
}
public synchronized Retrofit getRetrofit() {
return retrofit;
}
public int getRetrofitCode() {
return mRetrofitCode;
}
public synchronized void resetRetrofit(String url) {
mBaseUrl = url;
mClient = null;
mClient = createClient();
retrofit = null;
createRetrofit();
}
}</pre>
实现Callback,请求完成后用EventBus post出数据
<pre>
public class ApCallBack<T extends BaseResponse> implements Callback<T> {
T body;
private Object extra;
public ApCallBack(Class<? extends BaseResponse> body) {
this(body, null);
}
public ApCallBack(Class<? extends BaseResponse> body, Object extra) {
this.extra = extra;
try {
this.body = (T) body.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (response.isSuccessful()) {
BaseResponse bean = response.body();
if (extra != null) {
bean.extra = extra;
}
EventBus.getDefault().post(bean);
} else {
onFailure(call, new Throwable("HTTP STATUS CODE " + response.code()));
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
if (body == null) {
body = (T) new BaseResponse();
}
if (extra != null) {
body.extra = extra;
}
body.code = Http.ERROR_CODE_FAILURE;
body.desc = getFailureDesc();
EventBus.getDefault().post(body);
}
protected String getFailureDesc() {
return "network error";
}
}</pre>
Manager的一个基类, annotation processor 把Retrofit的接口生成Manager的基类
/**
* 基类,用于创建接口相关service
* Created by baofei on 2016/9/22.
*/
public class BaseManager<T> {
private int mRetrofitCode;
private T service;
public BaseManager() {
create();
}
private void create() {
mRetrofitCode = RetrofitManager.getInstance().getRetrofitCode();
service = (T) RetrofitManager.getInstance().getRetrofit().create(getT());
}
private Class getT() {
Type genType = getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
return (Class) params[0];
}
/**
* 获取T相关接口service类
*
* @return T的具体实现
*/
public T getService() {
if(mRetrofitCode != RetrofitManager.getInstance().getRetrofitCode()){
resetService();
}
return service;
}
/**
* 切换环境重置service
*/
public void resetService() {
create();
}
}```
http请求接口
``` @Manager
public interface ApiService {
@POST("/api/addr/getDefaultAddr")
Call<ResultBean> getDefaultAddr();
}```
运行编译时,annotation processor根据ApiService 和BaseManager生成如下代码,代码生成位置为build/generated/source/apt里
public final class ApiServiceManager extends BaseManager<ApiService> {
private static ApiServiceManager sApiServiceManager;
public static synchronized ApiServiceManager getInstance() {
if (sApiServiceManager == null) {
sApiServiceManager = new ApiServiceManager();
}
return sApiServiceManager;
}
public Call<ResultBean> getDefaultAddr() {
Call<ResultBean> call = getService().getDefaultAddr();
call.enqueue(new ApCallBack<ResultBean>(ResultBean.class));
return call;
}
}
代码中就可以使用 ApiServiceManager.getInstance().getDefaultAddr();