1. 程式人生 > >OkHttp架構——三層網路架構封裝(最實用的框架)

OkHttp架構——三層網路架構封裝(最實用的框架)

這裡寫圖片描述
圖片是以截圖開源中國的登入介面

介紹

開發中我們要使用到不同的網路的工具,如xUtils、OKHttp、NoHttp等工具,根據開發的不同情況,需要更換工具,這樣在Activity需要不斷的更換程式碼,耦合性比較高。
因此我們需要來搭建網路架構,進行架構封裝,解耦操作,優化程式碼量,降低耦合性

1、登入Activity請求資料為例,對OkHttp進行封裝

這是一段OKHttp網路工具使用的普遍流程,用來請求登入的賬戶和密碼資料,這樣使用的弊端:
1.程式碼量比價冗雜
2.在獲取不同的資料的時候,程式碼重複率高,網路物件不斷建立,消耗記憶體
3.在更該網路地址或者網路工具的時候,需要進行一個一個更改,並且修改你自己的原始碼。浪費時間,降低工作效率

public class LoginActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        log();
    }
/**登入方法**/
    private void log() {
        //獲取例項
         OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(3000
, TimeUnit.MILLISECONDS)//獲取資料並讀取資料的超時時間 .connectTimeout(3000,TimeUnit.MILLISECONDS)//連線超時時間 .build(); String url = "http://www.oschina.com/api?action=login&account=xx&password=xx";//登入請求資料 //獲取請求 Request request = new Request.Builder().url(url).build(); Call call = client.newCall(request); //實現回撥
call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { //獲取資料成功 String json = response.body();//獲取Json資料或者Xml資料,以字串形式展示 //InputStream inputStream = response.body().byteStream();或者是獲取資料字元輸入流 } @Override public void onFailure(Call call, IOException e) { //獲取資料失敗 } }); }

一:第一層封裝

1、提取 NetClient,整個任務棧中保證只有一個OkHttpClient物件就行

public class NetClient {

 private final OkHttpClient client;
    private OkHttpClient getClient(){
        //獲取例項
         OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(3000, TimeUnit.MILLISECONDS)//獲取資料並讀取資料的超時時間
                .connectTimeout(3000,TimeUnit.MILLISECONDS)//連線超時時間
                .build();
        return client;
    }
}

2、實現NetClient的單例模式,保證只有一個物件

public class NetClient {

    private static NetClient netClient;

    private NetClient(){
        client = getClient();
    }
  //單例模式
    public static NetClient getInstance(){
        if (netClient==null){
            netClient = new NetClient();
        }
        return netClient;
    }


    private final OkHttpClient client;

    private OkHttpClient getClient(){
        //獲取例項
         OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(3000, TimeUnit.MILLISECONDS)//獲取資料並讀取資料的超時時間
                .connectTimeout(3000,TimeUnit.MILLISECONDS)//連線超時時間
                .build();
        return client;
    }
    }

3、封裝請求方法

public class NetClient {

    private static NetClient netClient;

    private NetClient(){
        client = getClient();
    }

    public static NetClient getInstance(){
        if (netClient==null){
            netClient = new NetClient();
        }
        return netClient;
    }


    private final OkHttpClient client;

    private OkHttpClient getClient(){
         //獲取例項
         OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(3000, TimeUnit.MILLISECONDS)//獲取資料並讀取資料的超時時間
                .connectTimeout(3000,TimeUnit.MILLISECONDS)//連線超時時間
                .build();
        return client;
    }
//封裝請求方法,傳入一個url,以及使用自己定義的介面 MyCallBack 
    1:為什麼要自己定義callback介面呢?
    因為我們如果不更換介面,繼續使用OKHttp的callback,你一旦更換網路工具,你的原始碼就必須的更改

    public void doGet(String url, final MyCallBack callback){
        Request request = new Request.Builder().url(url).build();

        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 更新介面..
                callback.onFailure(-1);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.code()==200){
                    InputStream inputStream = response.body().byteStream();
                    callback.onResponse(inputStream);
                }else{
                    callback.onFailure(response.code());
                }

            }
        });
    }
}

二:第二層封裝

1、自定義介面MyCallBack。解耦網路回撥。API 可以不再關心底層的網路類。

public interface MyCallBack {

    void onFailure(int code);//失敗方法,引數是請求碼,來判斷獲取資料的情況

    void onResponse(InputStream in);//請求成功,傳入一個輸入流引數
}

三:第三層封裝

1、 提取 NetApi ,封裝 API 請求引數。介面上可以不再關心網路引數
在NetApi中定義logIN方法,這樣就實現網路引數更改變動,“一處改,百處變”

public class NetApi {
    private static final String HOST = "http://www.oschian.com/";

    public static void login(String account, String password, MyCallBack callback) {
        String url = HOST + "api?action=login&name="+account+"&mima="+password;
        NetClient.getInstance().doGet(url,callback);
    }
}

2、最後Activity中程式碼實現網路請求,只需要一行程式碼就可以

public class LoginActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        log();
    }
    /**登入請求**/
     private void log() {
        NetApi.login("xxx","xxx",new MyCallBack() {
            @Override
            public void onFailure(int code) {
                // 獲取資料失敗
            }
            @Override
            public void onResponse(InputStream in) {
                // 解析資料, 更新介面..
            }
        });
      }
    }