android 网络框架-Retrofit(三)

简单实现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和Callback
MyCall .class

public 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) {

            }
        });
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于Android项目中的网络请求,RxJava、Retrofit和MVP是常用的框架组合。下面是一个简单的网络框架封装示例: 首先,在项目中引入RxJava和Retrofit的依赖。 ``` implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' ``` 然后,创建一个Retrofit的单例类,用于进行网络请求的初始化和配置。 ```java public class RetrofitClient { private static Retrofit retrofit; private static final String BASE_URL = "https://api.example.com/"; public static Retrofit getClient() { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } return retrofit; } } ``` 接下来,创建一个ApiService接口,定义网络请求的方法。 ```java public interface ApiService { @GET("users") Observable<List<User>> getUsers(); } ``` 然后,创建一个DataManager类,用于管理网络请求。 ```java public class DataManager { private ApiService apiService; public DataManager() { apiService = RetrofitClient.getClient().create(ApiService.class); } public Observable<List<User>> getUsers() { return apiService.getUsers(); } } ``` 最后,在MVP的Presenter中调用DataManager类进行网络请求。 ```java public class UserPresenter { private UserView userView; private DataManager dataManager; public UserPresenter(UserView userView) { this.userView = userView; dataManager = new DataManager(); } public void getUsers() { dataManager.getUsers() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<User>>() { @Override public void onSubscribe(Disposable d) { // 在请求开始时的操作 } @Override public void onNext(List<User> users) { // 请求成功返回数据时的操作 userView.showUsers(users); } @Override public void onError(Throwable e) { // 请求失败时的操作 userView.showError(e.getMessage()); } @Override public void onComplete() { // 请求完成时的操作 } }); } } ``` 这样,就完成了一个简单的Android RxJava + Retrofit + MVP网络框架封装。你可以根据自己的需要,进行进一步的封装和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安卓兼职framework应用工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值