android网络框架代码重构

由于技术的更新发展,新技术新框架层出不穷。如果代码没有重构或者重构的不好,会造成很多问题,比如项目中某个框架过时不能用了,如果没有重构,在项目中每个用过该框架的地方都要一一修改,如果项目小还好,如果项目很大,那改动起来工作量会很大。怎么让自己项目不因框架的更新而发生改动,或者改动很小?这就需要代码重构了。怎么进行代码重构?下面以网络框架为例,进行代码重构。

首先,在项目-app下build.gradle下添加依赖:

implementation 'com.android.volley:volley:1.1.0'
implementation 'com.google.code.gson:gson:2.2.4'
implementation 'com.squareup.okhttp3:okhttp:3.4.1'

创建接口IHttpProcessor:

public interface IHttpProcessor {
    //该类相当于房地产公司,拥有卖房能力(对应网络请求,具有访问网络能力)
    void post(String url, Map params,ICallback callback);
}

创建接口ICallback:

public interface ICallback {

    void onSuccess(String result);

    void onFailure();
}

创建HttpCallback继承ICallback :

public abstract class HttpCallback implements ICallback {
    //将网络访问框架得到的数据转为json对象,再转换为实体对象
    @Override
    public void onSuccess(String result) {
        Gson gson = new Gson();
        Class claz = analysisClassInfo(this);
        Result o = (Result) gson.fromJson(result,claz);
        onSuccess(o);
    }

    private Class analysisClassInfo(Object object) {
        //得到HttpCallback后的泛型
        Type genType = object.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType) genType).getActualTypeArguments();
        return (Class)actualTypeArguments[0];
    }

    public abstract void onSuccess(Result objResult);

    @Override
    public void onFailure() {

    }
}

创建HttpHelper:

public class HttpHelper {
    private static HttpHelper instance;
    private HttpHelper(){}
    public static HttpHelper getInstance(){
        if(instance==null){
            synchronized (HttpHelper.class){
                if(instance==null) {
                    instance=new HttpHelper();
                }
            }
        }
        return instance;
    }
    //需要持有一个有房的人,相当于持有某个第三方网络框架
    private static IHttpProcessor mHttpProcessor;
    public static void init(IHttpProcessor httpProcessor){
        mHttpProcessor=httpProcessor;
    }

    public void post(String url, Map params,ICallback callback){
        //调用具体的第三方的post
        String pjurl=appendParams(url,params);
        mHttpProcessor.post(pjurl,params,callback);
    }

    private String appendParams(String url,Map params) {
        if(params == null || params.isEmpty()) {
            return url;
        }
        StringBuilder urlBuilder = new StringBuilder(url);
        if(urlBuilder.indexOf("?") <= 0) {
            urlBuilder.append("?");
        } else {
            if(!urlBuilder.toString().endsWith("?")) {
                urlBuilder.append("&");
            }
        }
        for (Map.Entry entry : params.entrySet()){
            urlBuilder.append("&"+entry.getKey()).append("=").append(enencode(entry.getValue().toString()));
        }
        return urlBuilder.toString();
    }

    private String enencode(String toString) {
        try {
            return URLEncoder.encode(toString,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new RuntimeException("encode fail");
        }
    }
}

如果使用的是volley框架,那么创建VolleyProcessor继承IHttpProcessor:

public class VolleyProcessor implements IHttpProcessor {
    private static RequestQueue mQueue = null;
    public VolleyProcessor(Context context){
        mQueue = Volley.newRequestQueue(context);
    }
    @Override
    public void post(String url, Map params, ICallback callback) {
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                callback.onSuccess(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        mQueue.add(stringRequest);
    }
}

如果使用的是OKhttp框架,那么创建OkhttpProcessor继承IHttpProcessor:

public class OkhttpProcessor implements IHttpProcessor {
    private OkHttpClient mOkHttpClient;
    private Handler myHandler;
    public OkhttpProcessor(){
        mOkHttpClient= new OkHttpClient();
        myHandler = new Handler();
    }
    @Override
    public void post(String url, Map params, ICallback callback) {
        RequestBody requestBody = appendBody(params);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()) {
                    String str = response.body().string();
                    myHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onSuccess(str);
                        }
                    });
                }
            }
        });
    }

    private RequestBody appendBody(Map params) {
        FormBody.Builder body = new FormBody.Builder();
        if(params == null || params.isEmpty()) {
            return body.build();
        }
        for (Map.Entry entry : params.entrySet()){
            body.add(entry.getKey(),entry.getValue().toString());
        }
        return body.build();
    }
}

创建MyApplication继承Application,在onCreate方法内初始化要使用的框架,并在AndroidManifest.xml中的application中添加

android:name=".MyApplication":

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
//        HttpHelper.init(new VolleyProcessor(this));
        HttpHelper.init(new OkhttpProcessor());
    }
}

如果要更换框架,在application中进行切换即可。

在网络框架调用页面调用封装后的框架,这里以MainActivity为例:

public class MainActivity extends AppCompatActivity {
    private String url="http://v.juhe.cn/historyWeather/citys";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Map params = new HashMap<>();
        params.put("province_id",1);
        params.put("key","bb52107206585ab074f5e59a8c73875b");
        HttpHelper.getInstance().post(url, params, new HttpCallback() {
            @Override
            public void onSuccess(ResponseBean objResult) {
                Log.e("===",objResult.toString());
            }
        });
    }
}

这样在框架调用页面就不会出现具体的某个框架,而是使用重构后的代码。如果框架改动,只需要改动少部分的代码即可,工作量大为减少。

例子中的url="http://v.juhe.cn/historyWeather/citys?province_id=1&key=bb52107206585ab074f5e59a8c73875b"返回的json数据为:

{"resultcode":"112","reason":"当前可请求的次数不足","result":null,"error_code":10012}

根据json结构创建bean对象ResponseBean:

public class ResponseBean {
    private String reason;
    private int resultCode;

    public ResponseBean() {
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public int getResultCode() {
        return resultCode;
    }

    public void setResultCode(int resultCode) {
        this.resultCode = resultCode;
    }

    @Override
    public String toString() {
        return "ResponseBean{" +
                "reason='" + reason + '\'' +
                ", resultCode=" + resultCode +
                '}';
    }
}

经测试,可以很便捷的切换框架。

源码下载

你可能感兴趣的:(Android)