OkHttp架構——三層網路架構封裝(最實用的框架)
阿新 • • 發佈:2019-02-15
圖片是以截圖開源中國的登入介面
介紹
開發中我們要使用到不同的網路的工具,如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) {
// 解析資料, 更新介面..
}
});
}
}