简单实现Retrofit(替代Okhttp)

1.定义注解参数

@Documented@Target(PARAMETER)@Retention(RUNTIME)public @interface Field {    String value();}@Documented@Target(METHOD)@Retention(RUNTIME)public @interface Get {    String value() default "";}@Documented@Target(METHOD)@Retention(RUNTIME)public @interface Post {    String value() default "";}2.实现回调接口Call和CallbackMyCall .classpublic interface MyCall {     //执行网络请求(同步:在当前网络)     String execute() throws Exception;    //在子线程请求网络    void enqueue(MyCallback callback);}MyCallback .class/** * 网络请求回调接口 */public interface MyCallback {  void onResponse( String response);  void onFailure( Exception e);}SystemHttpCall .class/** * Created by Xionghu on 2017/8/14. * Desc: 具体的实现类发送请求 */public class SystemHttpCall implements MyCall {    private MyServiceMethod serviceMethod;    public SystemHttpCall(MyServiceMethod serviceMethod) {        this.serviceMethod = serviceMethod;    }    @Override    public String execute() throws Exception {        if (serviceMethod.isPost()) {            return HttpUtils.post(serviceMethod.baseUrl(), serviceMethod.getParam());        } else {            return HttpUtils.get(serviceMethod.baseUrl());        }    }    @Override    public void enqueue(MyCallback callback) {        HttpTask httpTask = new HttpTask(this, callback);        httpTask.execute();    }    public class HttpTask extends AsyncTask<Void, Void, String> {        private SystemHttpCall httpCall;        private MyCallback callback;        private HttpTask(SystemHttpCall httpCall, MyCallback callback) {            this.httpCall = httpCall;            this.callback = callback;        }        @Override        protected String doInBackground(Void... params) {            try {                return httpCall.execute();            } catch (Exception e) {                e.printStackTrace();            }            return null;        }        @Override        protected void onPostExecute(String result) {            if (this.callback != null) {                if (result != null) {                    this.callback.onResponse(result);                } else {                    this.callback.onFailure(new Exception("网络异常!"));                }            }        }    }}

3.解析注解方法获取相应参数

public class MyServiceMethod {    private Builder builder;    public MyServiceMethod(Builder builder) {        this.builder = builder;    }    public boolean isPost() {        return this.builder.isPost;    }    public Map<String, Object> getParam() {        return this.builder.paramMap;    }    public String baseUrl() {        StringBuffer buffer = new StringBuffer(                this.builder.retrofit.getBaseUrl() + this.builder.relativeUrl);        if (!isPost()) {            // 如果你不是Post请求,是get请求,需要拼接参数地址            if (this.builder.paramMap != null) {                Set<String> keySet = this.builder.paramMap.keySet();                if (keySet.size() > 0) {                    buffer.append("?");                }                for (String key : keySet) {                    Object value = this.builder.paramMap.get(key);                    buffer.append(key);                    buffer.append("=");                    buffer.append(value);                    buffer.append("&");                }                buffer.deleteCharAt(buffer.length() - 1);            }        }        return buffer.toString();    }    static final class Builder {        final MyRetrofit retrofit;        final Method method;        final Annotation[] methodAnnotations;        final Annotation[][] parameterAnnotationsArray;        String relativeUrl;        // 参数集合        Map<String, Object> paramMap;        Object[] args;        boolean isPost;        public Builder(MyRetrofit retrofit, Method method, Object[] args) {            this.retrofit = retrofit;            this.method = method;            // 方法注解列表(相当于我们的LoginService中的: @POST和@FormUrlEncoded......)            this.methodAnnotations = method.getAnnotations();            // 方法参数注解列表(相当于我们的LoginService中的: @Field......)            this.parameterAnnotationsArray = method.getParameterAnnotations();            this.args = args;            this.paramMap = new HashMap<String, Object>();        }        public MyServiceMethod build() {            // 循环遍历方法注解列表            for (Annotation annotation : methodAnnotations) {                parseMethodAnnotation(annotation);            }            int parameterCount = parameterAnnotationsArray.length;            for (int p = 0; p < parameterCount; p++) {                Annotation[] parameterAnnotations = parameterAnnotationsArray[p];                parseParameterAnnotation(p, parameterAnnotations);            }            return new MyServiceMethod(this);        }        /**         * 解析方法注解         *         * @param annotation         */        public void parseMethodAnnotation(Annotation annotation) {            // 首先判断注解类型(解析目的:获取接口名称,用于拼接地址)            if (annotation instanceof Get) {                this.relativeUrl = ((Get) annotation).value();                isPost = false;            } else if (annotation instanceof Post) {                this.relativeUrl = ((Post) annotation).value();                isPost = true;            }        }        /**         * 解析参数注解         *         * @param p         * @param parameterAnnotations         */        private void parseParameterAnnotation(int p,                                              Annotation[] parameterAnnotations) {            // 方法参数值            Object value = args[p];            // 遍历方法参数注解            for (Annotation annotation : parameterAnnotations) {                // 首先需要判断该注解的类型                if (annotation instanceof Field) {                    Field field = (Field) annotation;                    // 参数的名称(接口参数名称,服务器接口规定的)                    String key = field.value();                    paramMap.put(key, value);                }            }        }    }}

4.定义MyRetrofit框架

public class MyRetrofit {    // 缓存方法(为了避免重复加载方法注解,从而耗费性能)    private final Map<Method, MyServiceMethod> serviceMethodCache = new LinkedHashMap<Method, MyServiceMethod>();    public String getBaseUrl() {        return baseUrl;    }    public void setBaseUrl(String baseUrl) {        this.baseUrl = baseUrl;    }    private String baseUrl;   private MyRetrofit(String baseUrl){       this.baseUrl = baseUrl;   }   public <T> T create(Class<T> service){       //动态代理实现       return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {           @Override           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {               MyServiceMethod serviceMethod = loadServiceMethod(method, args);               SystemHttpCall httpCall = new SystemHttpCall(serviceMethod);               return httpCall;           }       });   }
// 第一步:解析方法(说白了解析方法注解和方法参数注解)// 第二步:实现网络请求
   protected MyServiceMethod loadServiceMethod(Method method, Object[] args) {        MyServiceMethod result;        synchronized (serviceMethodCache) {            result = serviceMethodCache.get(method);            if (result == null) {                result = new MyServiceMethod.Builder(this, method, args)                        .build();                serviceMethodCache.put(method, result);            }        }        return result;    }   public static final class Builder{       private String baseUrl;       public Builder baseUrl(String baseUrl){           this.baseUrl = baseUrl;           return this;       }       public MyRetrofit build(){           if(baseUrl == null){                throw new IllegalStateException("Base URL required.");           }           return new MyRetrofit(baseUrl);       }   }}

5.具体实现网络请求类
定义接口方法类

public interface MyRetrofitLoginService {@Post("user/login?platform=android&city_id=101&type=pwd&channel=baiduxi&version=3.2.0&os_version=6.0.1&device_id=866622020797175")    MyCall login(@Field("mobile") String name, @Field("password") String pwd);}简单封装请求工具类public class MyRetrofitTest {    private static String URL_SERVER = "http://api.cloud.test.haocaisong.cn/v2.0/";    public static void login(String name, String pwd, final SimpleSystemLogin.OnHttpResultListener onHttpResultListener) {        MyRetrofit myRetrofit = new MyRetrofit.Builder().baseUrl(URL_SERVER).build();        MyRetrofitLoginService loginService = myRetrofit.create(MyRetrofitLoginService.class);        MyCall myCall = loginService.login(name,pwd);        myCall.enqueue(new MyCallback() {            @Override            public void onResponse(String response) {                onHttpResultListener.onHttpResult(response);            }            @Override            public void onFailure(Exception e) {            }        });    }}

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. mybatisplus的坑 insert标签insert into select无参数问题的解决
  3. Python技巧匿名函数、回调函数和高阶函数
  4. Python list sort方法的具体使用
  5. python list.sort()根据多个关键字排序的方法实现
  6. android上一些方法的区别和用法的注意事项
  7. android实现字体闪烁动画的方法
  8. Android中dispatchDraw分析
  9. Android四大基本组件介绍与生命周期

随机推荐

  1. Android活跃用户总数达14亿人 平均每4个
  2. Android仿淘宝首页UI(附代源代码及示例图
  3. Android实习生面试记录-蘑菇街、网易等
  4. Android平板上开发应用的一点心得——精
  5. [置顶] 从源码角度分析Android(安卓)View
  6. Android的盈利方式---学习别人的经验
  7. 发布应用到Android市场 -- Android(安卓)
  8. android AOP实现之AspectJ
  9. 必须得明白Android内存管理,千万别把windo
  10. Android中使用语音引擎入门七步曲