Android 通用网络框架封装

随着我们Android不断的发展, 网络框架亦是层出不穷,亦是在不断进步之中。 我们面对网络框架的不断升级.
1.自己封装的网络框架
2.Xutil网络框架
3.AsyncyHttp网络框架


Volley 网络框架
OkHttp网络框架
Retrofit 网络框架


更新的网络框架。
随着历史的发展网络框架一直在变化,一直在升级。

每一次改动网络框架,就把app交互代码改变一次,那么成本将会急剧增加。
所以我们应该设计一个中间层 与 app交互进行隔离。

这里写图片描述

这里就用到代理模式
这有个网上流传最经典的(王婆 与 西门官人)虽然有点污 但是很贴切说明了 代理之间的关系。

这里写图片描述

代理 持有 被代理人的共同的方法。

我们拿到此代理, 将来被代理人发生变化时我们只需将代理持有对象变化即可。App交互之间代码则不需要改变

来看代码。

代理类,网络请求最后抽象出最基本最公共的 get 和 post请求。

import java.util.Map;

/**
 * Author : 
 * Time : 2017/6/16 15:41
 * Function :
 *      代理接口            代理和真正干活的类  的 共同实现的接口
 * Mail : zhangdanjiang_java@163.com
 */

public interface IHttpProcessor {
    // Get

    void get(String url, Map<String, Object> params, ICallBack callBack);
    //Post
    void post(String url, Map<String, Object> params, ICallBack callBack);
    //Update
    //Delete
    //...
}

回调借口 抽象出最基本的 请求成功和请求失败两个方法

/**
 * Author : 
 * Time : 
 * Function :
 *
 *    网络层走的是byte 网络给我们的最终的String
 *
 * Mail : zhangdanjiang_java@163.com
 */

public interface ICallBack {

    void onSuccess(String string);

    void onFailed(String string);


}

我们回调接口 再加一个层,用来将返回的数据进行Gson解析层。然后以泛型的形式 返回。

import com.google.gson.Gson;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Author : 
 * Time : 
 * Function :
 *
 *      利用泛型实现通用的回调接口
 *
 * Mail : zhangdanjiang_java@163.com
 */

public abstract class HttpCallback<Result> implements ICallBack {

    @Override
    public void onSuccess(String result) {
        Gson gson = new Gson();
        Class<?> cls = analysisClzzInfo(this);

        Result objResult = (Result) gson.fromJson(result, cls);
        onSuccess(objResult);
    }

    public abstract void onSuccess(Result result);

    /**
     * 利用反射获得类的信息
     * @param object
     * @return Class<?> 需要实现的Json解析类
     */
    private Class<?> analysisClzzInfo(Object object) {

        Type genType = getClass().getGenericSuperclass();

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        return (Class<?>) params[0];
    }

}

代理类 实现 公共代理IHttpProcessor的接口


import java.util.Map;

/**
 * Author :
 * Time : 
 * Function :
 *      代理类
 * Mail : zhangdanjiang_java@163.com
 */

public class HttpHelper implements IHttpProcessor{
    /**
     * 被代理的对象
     */
    private static IHttpProcessor mIHttpProcessor;

    private static HttpHelper instance;

    private HttpHelper(){

    }

    public static HttpHelper getInstance() {

        if (instance == null) {
            instance = new HttpHelper();
        }
        return instance;
    }

    /**
     * 初始化立即启动
     * 传入被代理的对象,Volly实现类 okHttp实现类 等等
     *
     */
    public static void init(IHttpProcessor httpProcessor){
        mIHttpProcessor = httpProcessor;
    }


    @Override
    public void get(String url, Map<String, Object> params, ICallBack callBack) {
        mIHttpProcessor.get(url, params, callBack);
    }

    @Override
    public void post(String url, Map<String, Object> params, ICallBack callBack) {
        mIHttpProcessor.post(url, params, callBack);
    }
}

编写Volly实现的类
自己找一个 Url 地址返回一个Json
编写一个Gosn的实体类 编写我们的具体Volly的网络请求配置


import android.content.Context;
import android.util.Log;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import java.util.Map;



/**
 * Author : 
 * Time : 
 * Function :
 * Mail : zhangdanjiang_java@163.com
 */

public class VolleyProcessor implements IHttpProcessor{

    private final static String TAG = "VolleyProcessor";

    private static RequestQueue mQueue = null;

    public VolleyProcessor(Context context) {
        mQueue = Volley.newRequestQueue(context);

    }

    @Override
    public void get(String url, Map<String, Object> params, final ICallBack callBack) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "onSuccess response==" + response);
                callBack.onSuccess(response);
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                String toString = "null";
                if (error != null) {
                    toString = error.toString();
                }
                Log.d(TAG, "onErrorResponse error ==" + toString);
                callBack.onFailed(error.toString());
            }
        });

        mQueue.add(stringRequest);

    }

    @Override
    public void post(String url, Map<String, Object> params, final ICallBack callBack) {

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {


            @Override
            public void onResponse(String response) {
                Log.d(TAG, "onSuccess response==" + response);
                callBack.onSuccess(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                String toString = "null";
                if (error != null) {
                    toString = error.toString();
                }
                Log.d(TAG, "onErrorResponse error ==" + toString);
                callBack.onFailed(error.toString());
            }
        });

        mQueue.add(stringRequest);
    }
}

Application 中对 代理设置使用哪一种网络框架


import android.app.Application;

/**
 * Created by jiang on 2017/6/17.
 */

public class MyApplication extends Application{

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

Gradle 文件配置 所需的网络框架

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.jing.demo01"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    compile 'org.xutils:xutils:3.5.0'
    compile 'com.google.code.gson:gson:2.8.1'
    compile 'com.github.erd:android-volley:1.0.0'
    compile 'com.squareup.okhttp3:okhttp:3.8.0'
}

配置网络请求设置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.jing.demo01">

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:name=".MyApplication"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

编写测试代码 我们测试一下
就可以成功请求到数据

package com.jing.demo01;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.jing.demo01.bean.RotateBean;

import java.util.HashMap;

public class MainActivity extends AppCompatActivity {

    private String url = HttpUtil.GET_SERIAL_ROTATE;

    private HashMap<String , Object> params = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //测试提交数据
        findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HttpHelper.getInstance().get(url, params, new HttpCallback<RotateBean>() {

                    @Override
                    public void onSuccess(RotateBean rotateBean) {
                        toast("请求成功");
                    }

                    @Override
                    public void onFailed(String string) {
                        toast("请求失败");
                    }
                });
            }
        });
        // 在测试
    }

    public void toast(String string){
        Toast.makeText(this, string , Toast.LENGTH_SHORT).show();
    }
}

我们Volly网络框架请求成功后
我们测试另一个网络框架OkHttp


import android.os.Handler;
import android.util.Log;

import java.io.IOException;
import java.util.Map;


import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by jiang on 
 */

public class OkHttpProcessor implements IHttpProcessor {
    private final String TAG = "OkHttpProcessor";

    private OkHttpClient mOkHttpClient;

    private Handler myHandler;

    public OkHttpProcessor() {
        mOkHttpClient = new OkHttpClient();
        myHandler = new Handler();
    }

    @Override
    public void get(String url, Map<String, Object> params, final ICallBack callBack) {
        final Request request = new Request.Builder()
                .get()
                .url(url)
                .build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure e ==" + e);
                callBack.onFailed(e.toString());
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (response == null) {
                    Log.d(TAG, "onSuccess response== null");
                    return;
                }
                Log.d(TAG, "onSuccess response==" + response.toString());
                if (response.isSuccessful()) {
                   final String result = response.body().string();
                    Log.d(TAG, "onSuccess result==" + result);
                    myHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onSuccess(result);
                        }
                    });

                } else {

                    myHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onFailed(response.message().toString());
                        }
                    });

                }
            }
        });
    }

    @Override
    public void post(String url, Map<String, Object> params,final ICallBack callBack) {
        RequestBody requestbody = appendBody(params);

        final Request request = new Request.Builder()
                .post(requestbody)
                .url(url)
                .build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call,final IOException e) {
                Log.d(TAG, "onFailure e ==" + e);
                myHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onFailed(e.toString());

                    }
                });

            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (response == null) {
                    Log.d(TAG, "onSuccess response== null");
                    return;
                }
                Log.d(TAG, "onSuccess response==" + response.toString());
                if (response.isSuccessful()) {
                    final String result = response.body().string();

                    myHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onSuccess(result);

                        }
                    });
                } else {
                    myHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onFailed(response.message().toString());

                        }
                    });

                }
            }
        });


    }

    /**
     * 快速构建参数
     * @param params
     * @return
     */
    private RequestBody appendBody(Map<String, Object> params) {
        FormBody.Builder body = new FormBody.Builder();
        if (params == null || params.isEmpty()) {
            return body.build();
        }

        for (Map.Entry<String, Object> entry:
             params.entrySet()) {
            body.add(entry.getKey(), entry.getValue().toString());
        }
        return body.build();
    }
}

我们需要注意 OkHttp是在子线程里面, 我们需要通过Handler将返回结果转到主线程里面

此时我们只需改一处配置 在Application里面改变代理配置,我们就可以从Volly框架转到OkHttp上面了。 而其他交互层代码 无感知的换了底层。

简单的书写 不足之处 还望指正
邮箱 zhangdanjiang_java@163.com
GitHub 地址 https://github.com/JiangGeJavaAndroid/Demo01

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值