preface

This article mainly explains the common network framework encapsulation of Android, and the implementation of a code to switch the mainstream network framework at will. Readers can also follow the ideas in this chapter to achieve other effects, such as switching permission request frameworks at will.

The characteristics of

Written this way, refactoring is easy!

What is isolation layer design?

Let me draw a picture to illustrate

Let’s take real life for example.

  • Consider the buyer (customer) as the APP we wrote;

  • Think of people (owners) as the mainstream network framework we approach (XUtils, OkHttp, OkGo….) ;

  • Real estate companies (such as Lianjia) are regarded as the services (POST, GET network request, etc.) needed by customers (our APP);

  • The salesman (intermediary) as the customer’s recommender;

then

If the App wants to realize the network request, it needs to find the salesman of the real estate company first. The salesman will get the list of the network frame (owner list) that has been settled in the real estate company and provide the user with choice. If the user is not satisfied with the house (network frame), he can change to another one at any time. And real estate company and salesman is this chapter so-called isolation layer.

The train of thought is understood clearly, then began actual combat operation

The first step is to create a real estate company called IHttpProcessor

/** * Real estate company */
public interface IHttpProcessor {
    // Have the ability to sell the house
    // Network access capability
    void post(String url, Map<String,Object> params, ICallback callback);
    void get(String url, Map<String,Object> params,ICallback callback);
}
Copy the code

Whether the transaction is successful is the callback ICallback

/** * the top-level callback interface */
public interface ICallback {
    void onSuccess(String result);
    void onFailure(String e);
}
Copy the code

And the ICallback extension, HttpCallback


/** * an implementation of the callback interface */
public abstract class HttpCallback<Result> implements ICallback{
    @Override
    public void onSuccess(String result) {
        // All the results back from the network are on result
        //1. What javaBean does the caller use to receive dataClass<? > clz=analysisClassInfo(this);
        //2. Turn String into A javaBean object and hand it to the user
        Gson gson=new Gson();
        Result objResult=(Result)gson.fromJson(result,clz);
        //3. Give the result to the user
        onSuccess(objResult);
    }

    public abstract void onSuccess(Result objResult);

    /** * Get the actual type of the input parameter */
    privateClass<? > analysisClassInfo(Object object){GetGenericSuperclass () returns an object of type
        // This object can be obtained containing primitive types, parameterizations, arrays, type variables, and primitive data types
        Type getType=object.getClass().getGenericSuperclass();
        Type[] params=((ParameterizedType)getType).getActualTypeArguments();
        return(Class<? >)params[0];
    }

    @Override
    public void onFailure(String e) {}}Copy the code

Code analysis: Why was this class created? Imagine, when the user, when the buyer is successful, does the customer have to have a contract, and all kinds of vouchers. And this class is the network request after the success of the data to do a layer of data analysis, try to deal with the complex data, to the upper layer to submit a very simple data structure.

Step 2, we create the owner and merge into the real estate company (OkHttp example)


public class OkHttpProcessor implements IHttpProcessor {

    private OkHttpClient mOkHttpClient;
    private Handler myHandler;

    public OkHttpProcessor(a){
        mOkHttpClient=new OkHttpClient();
        myHandler=new Handler(Looper.getMainLooper());
    }

    @Override
    public void post(String url, Map<String, Object> params,final ICallback callback) {
        final RequestBody requestBody=appendBody(params);
        Request request=new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result=response.body().string();
                if(response.isSuccessful()){
                    myHandler.post(new Runnable() {
                        @Override
                        public void run(a) { callback.onSuccess(result); }}); }else{
                    myHandler.post(new Runnable() {
                        @Override
                        public void run(a) { callback.onFailure(result); }}); }}@Override
            public void onFailure(Call call, IOException e) {
                myHandler.post(new Runnable() {
                    @Override
                    public void run(a) {
                        callback.onFailure("onFailure"); }}); }}); }@Override
    public void get(String url, Map<String, Object> params, ICallback callback) {}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());
        }
        returnbody.build(); }}Copy the code

Code analysis: This class OkHttpProcessor realizes the interface of real estate company, and realizes the corresponding network request service in corresponding real estate company service (POST, GET), so that the real estate company has the ability to process OkHttpProcessor corresponding to POST and GET.

The third step is to create an owner again and merge into a real estate company (XUtils example).

public class XUtilsProcessor implements IHttpProcessor {

    public XUtilsProcessor(MyApplication app){
        x.Ext.init(app);
    }

    @Override
    public void post(String url, Map<String, Object> params,final ICallback callback) {
        RequestParams requestParams=new RequestParams(url);
        x.http().post(requestParams, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                callback.onSuccess(result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {}@Override
            public void onCancelled(CancelledException cex) {}@Override
            public void onFinished(a) {}}); }@Override
    public void get(String url, Map<String, Object> params, ICallback callback) {}}Copy the code

To this, the real estate company had, the owner also had many, and also entered the real estate company. So now comes the salesman

Step 4: HttpHelper

public class HttpHelper implements IHttpProcessor {

    // Define an owner, the person who sells a house
    private static IHttpProcessor mIHttpProcessor=null;

    // Through an API to set which owner sells his house, (who completes the network access)
    public static void init(IHttpProcessor httpProcessor){
        mIHttpProcessor=httpProcessor;
    }

    / / the singleton
    private static HttpHelper instance;
    public static HttpHelper obtain(a){
        synchronized (HttpHelper.class){
            if(instance==null){
                instance=newHttpHelper(); }}return instance;
    }
    private HttpHelper(a){}




    /** * can you sell the house by yourself */
    @Override
    public void post(String url, Map<String, Object> params, ICallback callback) {
        //http://www.aaa.bbb/index?&user=jett&pwd=123
        //http://www.aaa.bbb/index
        //&user=jett&pwd=123
        String finalUrl=appendParams(url,params);
        mIHttpProcessor.post(url,params,callback);
    }

    @Override
    public void get(String url, Map<String, Object> params, ICallback callback) {}public static String appendParams(String url, Map<String,Object> 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<String,Object> entry:params.entrySet()){
            urlBuilder.append("&"+entry.getKey())
                    .append("=")
                    .append(encode(entry.getValue().toString()));
        }
        return urlBuilder.toString();
    }
    private static String encode(String str){
        try {
            return URLEncoder.encode(str,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw newRuntimeException(); }}}Copy the code

HttpHelper: HttpHelper is a real estate broker that implements the ability of the real estate company to sell a house, and init method for the client (APP) which house to sell (which network frame). The static variable mIHttpProcessor is the owner of the house that is about to sell, which is the network framework that we are going to use.

At this point, all the preparations have been made and we can now start trading

Step 5: Start trading

  • MyApplication
public class MyApplication extends Application {
    @Override
    public void onCreate(a) {
        super.onCreate();
// HttpHelper.init(new VolleyProcessor(this));
// HttpHelper.init(new XUtilsProcessor(this)); Determine which network framework to use
        HttpHelper.init(newOkHttpProcessor()); }}Copy the code
  • MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void click(View view) {
        String url="https://v.juhe.cn/historyWeather/citys";
        HashMap<String,Object> params=new HashMap<>();
        //https://v.juhe.cn/historyWeather/citys?&province_id=2&key=bb52107206585ab074f5e59a8c73875b
        params.put("province_id"."2");
        params.put("key"."bb52107206585ab074f5e59a8c73875b");
        HttpHelper.obtain().post(url, params, new HttpCallback<ResponceData>() {
            @Override
            public void onSuccess(ResponceData objResult) {
                Toast.makeText(MainActivity.this, objResult.getResultcode(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(String e) {
                super.onFailure(e); }}); }}Copy the code

ResponceData is the ResponceData entity that responds to a successful web request

In the next article, how to quickly switch mainstream frameworks using Hilt

The Demo address:Let me download