<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      OkHttp封裝

      前言

      上個知識點介紹了OKHttp的基本使用,在Activity中寫了大量訪問網絡的代碼,這種代碼寫起來很無聊,并且對技術沒什么提升。在真實的企業開發中,肯定是把這些代碼封裝起來,做一個庫,給Activity調用。

      封裝之前我們需要考慮以下這些問題:

      • 封裝基本的公共方法給外部調用。get請求,Post請求,PostFile
      • 官方建議OkHttpClient實例只new一次,那我們網絡請求庫可以做成單例模式。
      • 如果同一時間訪問同一個api多次,我們是不是應該取消之前的請求?
      • 如果用戶連接Http代理了,就不讓訪問,防止用戶通過抓包工具看我們的接口數據。
      • 每個接口都要帶上的參數如何封裝?例如app版本號,設備號,登錄之后的用戶token,這些參數可能每次請求都要帶上。
      • 返回的json字符串轉成實體對象
      • 訪問服務器是異步請求,如何在主線程中調用回調接口?

      代碼實現

      首先需要在線引用以下三個依賴庫

      compile 'com.squareup.okhttp3:okhttp:3.2.0' //okhttp
      compile 'com.google.code.gson:gson:2.7' //解析jsons數據
      compile 'io.github.lizhangqu:coreprogress:1.0.2' //上傳下載回調監聽
      

      新建一個HttpConfig類,用來配置一些請求參數,存儲請求服務器的公共參數。設置連接時間等。。。

      public class HttpConfig {
          private boolean debug=false;//true:debug模式
          private String userAgent="";//用戶代理 它是一個特殊字符串頭,使得服務器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。
          private boolean agent=true;//有代理的情況能不能訪問,true:有代理能訪問 false:有代理不能訪問
          private String tagName="Http";
      
          private int connectTimeout=10;//連接超時時間 單位:秒
          private int writeTimeout=10;//寫入超時時間 單位:秒
          private int readTimeout=30;//讀取超時時間 單位:秒
      
          //通用字段
          private List<NameValuePair> commonField=new ArrayList<>();
      
          public boolean isDebug() {
              return debug;
          }
      
          public void setDebug(boolean debug) {
              this.debug = debug;
          }
      
          public String getUserAgent() {
              return userAgent;
          }
      
          public void setUserAgent(String userAgent) {
              this.userAgent = userAgent;
          }
      
          public boolean isAgent() {
              return agent;
          }
      
          public void setAgent(boolean agent) {
              this.agent = agent;
          }
      
          public String getTagName() {
              return tagName;
          }
      
          public void setTagName(String tagName) {
              this.tagName = tagName;
          }
      
          public List<NameValuePair> getCommonField() {
              return commonField;
          }
      
          public int getConnectTimeout() {
              return connectTimeout;
          }
      
          public void setConnectTimeout(int connectTimeout) {
              this.connectTimeout = connectTimeout;
          }
      
          public int getWriteTimeout() {
              return writeTimeout;
          }
      
          public void setWriteTimeout(int writeTimeout) {
              this.writeTimeout = writeTimeout;
          }
      
          public int getReadTimeout() {
              return readTimeout;
          }
      
          public void setReadTimeout(int readTimeout) {
              this.readTimeout = readTimeout;
          }
      
          /**
           * 更新參數
           * @param key
           * @param value
           */
          public void updateCommonField(String key,String value){
              boolean result = true;
              for(int i=0;i<commonField.size();i++){
                  NameValuePair nameValuePair = commonField.get(i);
                  if(nameValuePair.getName().equals(key)){
                      commonField.set(i,new NameValuePair(key,value));
                      result = false;
                      break;
                  }
              }
              if(result){
                  commonField.add(new NameValuePair(key,value));
              }
          }
      
          /**
           * 刪除公共參數
           * @param key
           */
          public void removeCommonField(String key){
              for(int i=commonField.size()-1;i>=0;i--){
                  if(commonField.get(i).equals("key")){
                      commonField.remove(i);
                  }
              }
          }
      
          /**
           * 添加請求參數
           * @param key
           * @param value
           */
          public void addCommonField(String key,String value){
              commonField.add(new NameValuePair(key,value));
          }
      }
      

      我們給服務器提交表單數據都是通過name跟vulue的形式提交數據,封裝了NameValuePair類。如果是上傳文件,isFile設置true就行。

      public class NameValuePair {
          private String name;//請求名稱
          private String value;//請求值
          private boolean isFile=false;//是否是文件
      
          public NameValuePair(String name, String value){
              this.name=name;
              this.value = value;
          }
      
          public NameValuePair(String name, String value,boolean isFile){
              this.name=name;
              this.value = value;
              this.isFile=isFile;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
      
          public String getValue() {
              return value;
          }
      
          public void setValue(String value) {
              this.value = value;
          }
      
          public boolean isFile() {
              return isFile;
          }
      
          public void setFile(boolean file) {
              isFile = file;
          }
      }
      

      請求服務器成功或者失敗都會回調Callback接口,我們封裝HttpResponseHandler抽象類來實現這個接口,對服務器返回的數據以及狀態碼進行了簡單的過濾,最終最調用自己的onFailure跟onSuccess方法。

      public abstract class HttpResponseHandler implements Callback {
      	public HttpResponseHandler(){
      	}
      
      	public void onFailure(Call call, IOException e){
      		onFailure(-1,e.getMessage().getBytes());
      	}
      
      	public void onResponse(Call call, Response response) throws IOException {
      		int code =response.code();
      		byte[] body = response.body().bytes();
      		if(code>299){
      			onFailure(response.code(),body);
      		}else{
      			Headers headers = response.headers();
      			Header[] hs = new Header[headers.size()];
      
      			for (int i=0;i<headers.size();i++){
      				hs[i] = new Header(headers.name(i),headers.value(i));
      			}
      			onSuccess(code,hs,body);
      		}
      	}
      
      	public void onFailure(int status,byte[] data){
      	}
      
      //	public void onProgress(int bytesWritten, int totalSize) {
      //	}
      
      	public abstract void onSuccess(int statusCode, Header[] headers, byte[] responseBody);
      }
      

      Get請求封裝

      封裝后的HTTPCaller代碼如下,現在里面只有get請求,如果一下子把post請求跟postFile方法貼進來,代碼有點多。

      public class HTTPCaller {
      	private static HTTPCaller _instance = null;
      	private OkHttpClient client;//okhttp對象
      	private Map<String,Call> requestHandleMap = null;//以URL為KEY存儲的請求
      	private CacheControl cacheControl = null;//緩存控制器
      
      	private Gson gson = null;
      
      	private HttpConfig httpConfig=new HttpConfig();//配置信息
      
      	private HTTPCaller() {}
      
      	public static HTTPCaller getInstance(){
      		if (_instance == null) {
      			_instance = new HTTPCaller();
      		}
      		return _instance;
      	}
      
      	/**
      	 * 設置配置信息 這個方法必需要調用一次
      	 * @param httpConfig
           */
      	public void setHttpConfig(HttpConfig httpConfig) {
      		this.httpConfig = httpConfig;
      
      		client = new OkHttpClient.Builder()
      				.connectTimeout(httpConfig.getConnectTimeout(), TimeUnit.SECONDS)
      				.writeTimeout(httpConfig.getWriteTimeout(), TimeUnit.SECONDS)
      				.readTimeout(httpConfig.getReadTimeout(), TimeUnit.SECONDS)
      				.build();
      
      		gson = new Gson();
      		requestHandleMap = Collections.synchronizedMap(new WeakHashMap<String, Call>());
      		cacheControl =new CacheControl.Builder().noStore().noCache().build();//不使用緩存
      	}
      
      	public <T> void get(Class<T> clazz,final String url,Header[] header,final RequestDataCallback<T> callback) {
      		this.get(clazz,url,header,callback,true);
      	}
      
      	/**
      	 * get請求
      	 * @param clazz json對應類的類型
      	 * @param url 請求url
      	 * @param header 請求頭
      	 * @param callback 回調接口
      	 * @param autoCancel 是否自動取消 true:同一時間請求一個接口多次  只保留最后一個
           * @param <T>
           */
      	public <T> void get(final Class<T> clazz,final String url,Header[] header,final RequestDataCallback<T> callback, boolean autoCancel){
      		if (checkAgent()) {
      			return;
      		}
      		add(url,getBuilder(url, header, new MyHttpResponseHandler(clazz,url,callback)),autoCancel);
      	}
      
      	private Call getBuilder(String url, Header[] header, HttpResponseHandler responseCallback) {
      		url=Util.getMosaicParameter(url,httpConfig.getCommonField());//拼接公共參數
      		Request.Builder builder = new Request.Builder();
      		builder.url(url);
      		builder.get();
      		return execute(builder, header, responseCallback);
      	}
      
      	private Call execute(Request.Builder builder, Header[] header, Callback responseCallback) {
      		boolean hasUa = false;
      		if (header == null) {
      			builder.header("Connection","close");
      			builder.header("Accept", "*/*");
      		} else {
      			for (Header h : header) {
      				builder.header(h.getName(), h.getValue());
      				if (!hasUa && h.getName().equals("User-Agent")) {
      					hasUa = true;
      				}
      			}
      		}
      		if (!hasUa&&!TextUtils.isEmpty(httpConfig.getUserAgent())){
      			builder.header("User-Agent",httpConfig.getUserAgent());
      		}
      		Request request = builder.cacheControl(cacheControl).build();
      		Call call = client.newCall(request);
      		call.enqueue(responseCallback);
      		return call;
      	}
      
      	public class MyHttpResponseHandler<T> extends HttpResponseHandler {
      		private Class<T> clazz;
      		private String url;
      		private RequestDataCallback<T> callback;
      
      		public MyHttpResponseHandler(Class<T> clazz,String url,RequestDataCallback<T> callback){
      			this.clazz=clazz;
      			this.url=url;
      			this.callback=callback;
      		}
      
      		@Override
      		public void onFailure(int status, byte[] data) {
      			clear(url);
      			try {
      				printLog(url + " " + status + " " + new String(data, "utf-8"));
      			} catch (UnsupportedEncodingException e) {
      				e.printStackTrace();
      			}
      			sendCallback(callback);
      		}
      
      		@Override
      		public void onSuccess(int status,final Header[] headers, byte[] responseBody) {
      			try {
      				clear(url);
      				String str = new String(responseBody,"utf-8");
      				printLog(url + " " + status + " " + str);
      				T t = gson.fromJson(str, clazz);
      				sendCallback(status,t,responseBody,callback);
      			} catch (Exception e){
      				if (httpConfig.isDebug()) {
      					e.printStackTrace();
      					printLog("自動解析錯誤:" + e.toString());
      				}
      				sendCallback(callback);
      			}
      		}
      	}
      
      	private void autoCancel(String function){
      		Call call = requestHandleMap.remove(function);
      		if (call != null) {
      			call.cancel();
      		}
      	}
      
      	private void add(String url,Call call) {
      		add(url,call,true);
      	}
      
      	/**
      	 * 保存請求信息
      	 * @param url 請求url
      	 * @param call http請求call
      	 * @param autoCancel 自動取消
           */
      	private void add(String url,Call call,boolean autoCancel) {
      		if (!TextUtils.isEmpty(url)){
      			if (url.contains("?")) {//get請求需要去掉后面的參數
      				url=url.substring(0,url.indexOf("?"));
      			}
      			if(autoCancel){
      				autoCancel(url);//如果同一時間對api進行多次請求,自動取消之前的
      			}
      			requestHandleMap.put(url,call);
      		}
      	}
      
      	private void clear(String url){
      		if (url.contains("?")) {//get請求需要去掉后面的參數
      			url=url.substring(0,url.indexOf("?"));
      		}
      		requestHandleMap.remove(url);
      	}
      
      	private void printLog(String content){
      		if(httpConfig.isDebug()){
      			Log.i(httpConfig.getTagName(),content);
      		}
      	}
      
      	/**
      	 * 檢查代理
      	 * @return
      	 */
      	private boolean checkAgent() {
      		if (httpConfig.isAgent()){
      			return false;
      		} else {
      			String proHost = android.net.Proxy.getDefaultHost();
      			int proPort = android.net.Proxy.getDefaultPort();
      			if (proHost==null || proPort<0){
      				return false;
      			}else {
      				Log.i(httpConfig.getTagName(),"有代理,不能訪問");
      				return true;
      			}
      		}
      	}
      
      	//更新字段值
      	public void updateCommonField(String key,String value){
      		httpConfig.updateCommonField(key,value);
      	}
      
      	public void removeCommonField(String key){
      		httpConfig.removeCommonField(key);
      	}
      
      	public void addCommonField(String key,String value){
      		httpConfig.addCommonField(key,value);
      	}
      
      	private <T> void sendCallback(RequestDataCallback<T> callback){
      		sendCallback(-1,null,null,callback);
      	}
      
      	private <T> void sendCallback(int status,T data,byte[] body,RequestDataCallback<T> callback){
      		CallbackMessage<T> msgData = new CallbackMessage<T>();
      		msgData.body = body;
      		msgData.status = status;
      		msgData.data = data;
      		msgData.callback = callback;
      
      		Message msg = handler.obtainMessage();
      		msg.obj = msgData;
      		handler.sendMessage(msg);
      	}
      
      	private Handler handler=new Handler(){
      		@Override
      		public void handleMessage(Message msg) {
      			CallbackMessage data = (CallbackMessage)msg.obj;
      			data.callback();
      		}
      	};
      
      	private class CallbackMessage<T>{
      		public RequestDataCallback<T> callback;
      		public T data;
      		public byte[] body;
      		public int status;
      
      		public void callback(){
      			if(callback!=null){
      				if(data==null){
      					callback.dataCallback(null);
      				}else{
      					callback.dataCallback(status,data,body);
      				}
      			}
      		}
      	}
      }
      
      • getInstance 用來獲取對象類的對象,因為是單例模式,這個方法無論調用多少次只會創建一個對象。
      • setHttpConfig 創建了HTTPCaller對象的時候必須要調用該方法來初始化一些對象,通過參數httpConfig獲取連接時間來初始化OkHttpClient對象,用WeakHashMap來存儲每一次的請求。還需要初始化Gson對象。
      • get 有兩個同名方法,這是方法重載,如果你想同一時間訪問同一接口多次,用下面那個方法,最后一個一個參數傳false,如果沒有要求就用上面那個。我們看到在get方法里面首先調用了getBuilder發起get請求,getBuilder會返回一個Call對象,這個方法的第三個參數傳入一個MyHttpResponseHandler對象,這個對象實現了Callback接口,請求服務器成功或者失敗會把結果回調這個類。最外層調用了add方法,請求url作為key,Call作為vuelue保存到map里面。
      • getBuilder 這個方法的第一行調用Util的getMosaicParameter方法拼接公共參數,然后根據url生成Request.Builder對象,繼續調用execute。
      • execute 首先設置請求頭信息,一般沒有特殊要求請求都不需要設置,通過builder對象的cacheControl方法設置緩存控制,通過build方法生成Request,通過OkHttpClient對象的newCall方法生成一個call對象,最后調用enqueue方法,進行異步請求,傳入一個回調接口。

      MyHttpResponseHandler類繼承我們自己寫的HttpResponseHandler抽象類,重寫兩個方法onFailure跟onSuccess。

      onFailure 先從map中刪除這個請求,打印錯誤log,發送回調。
      onSuccess 先從map中刪除這個請求,把json字符串轉成對象。發送回調。
      
      • autoCancel 從map中刪除這個請求,調用Call.call取消http請求。
      • add 有兩個同名的方法,方法重載。我們來分析后面這個。首先判斷這個url是否為空,為空的話肯定啥也干不了。然后需要截取?前面的信息,不然參數不一樣我們就沒法判斷是不是同一時間多次請求同一接口了。然后判斷要不要自動取消。最后存入map。經過前面的分析我們都知道發起get請求的時候會調用add方法把call請求保存到map里面去,請求成功回調中會把call從map中刪除。假如手機網絡狀態不穩定,同一時間請求了10次同一個接口,都沒有回調回來,這也是為什么我們需要在添加的時候會自動取消之前的請求。
      • clear 從map中刪除請求
      • printLog 打印log
      • sendCallback 有兩個方法,方法重載。把返回內容,狀態,byte數組,回調封裝到CallbackMessage對象,通過handerl把這個對象發送到主線程中,然后調用CallbackMessage對象的callback方法。

      Post請求封裝

      通過以上對HTTPCaller類各個方法的解釋,相信你知道了get請求服務器的整個調用流程。現在我們對HTTPCaller類增加post請求的方法以及上傳文件的方法。postFile方法增加了ProgressUIListener參數,通過這個接口監聽上傳文件進度的回調。

      public <T> void post(final Class<T> clazz, final String url, Header[] header, List<NameValuePair> params, final RequestDataCallback<T> callback) {
              this.post(clazz,url, header, params, callback,true);
      }
      
      /**
       *
       * @param clazz json對應類的類型
       * @param url  請求url
       * @param header 請求頭
       * @param params 參數
       * @param callback 回調
       * @param autoCancel 是否自動取消 true:同一時間請求一個接口多次  只保留最后一個
       * @param <T>
       */
      public <T> void post(final Class<T> clazz,final String url, Header[] header, final List<NameValuePair> params, final RequestDataCallback<T> callback, boolean autoCancel) {
          if (checkAgent()) {
              return;
          }
          add(url,postBuilder(url, header, params, new HTTPCaller.MyHttpResponseHandler(clazz,url,callback)),autoCancel);
      }
      
      private Call postBuilder(String url, Header[] header, List<NameValuePair> form, HttpResponseHandler responseCallback) {
          try {
              if (form == null) {
                  form = new ArrayList<>(2);
              }
              form.addAll(httpConfig.getCommonField());//添加公共字段
              FormBody.Builder formBuilder = new FormBody.Builder();
              for (NameValuePair item : form) {
                  formBuilder.add(item.getName(), item.getValue());
              }
              RequestBody requestBody = formBuilder.build();
              Request.Builder builder = new Request.Builder();
              builder.url(url);
              builder.post(requestBody);
              return execute(builder, header, responseCallback);
          } catch (Exception e) {
              if (responseCallback != null)
                  responseCallback.onFailure(-1, e.getMessage().getBytes());
          }
          return null;
      }
      
      /**
       * 上傳文件
       * @param clazz json對應類的類型
       * @param url 請求url
       * @param header 請求頭
       * @param form 請求參數
       * @param callback 回調
       * @param <T>
       */
      public <T> void postFile(final Class<T> clazz, final String url, Header[] header,List<NameValuePair> form,final RequestDataCallback<T> callback) {
          postFile(url, header, form, new HTTPCaller.MyHttpResponseHandler(clazz,url,callback),null);
      }
      
      /**
       * 上傳文件
       * @param clazz json對應類的類型
       * @param url 請求url
       * @param header 請求頭
       * @param form 請求參數
       * @param callback 回調
       * @param progressUIListener  上傳文件進度
       * @param <T>
       */
      public <T> void postFile(final Class<T> clazz, final String url, Header[] header,List<NameValuePair> form,final RequestDataCallback<T> callback,ProgressUIListener progressUIListener) {
          add(url, postFile(url, header, form, new HTTPCaller.MyHttpResponseHandler(clazz,url,callback),progressUIListener));
      }
      
      /**
       * 上傳文件
       * @param clazz json對應類的類型
       * @param url 請求url
       * @param header 請求頭
       * @param name 名字
       * @param fileName 文件名
       * @param fileContent 文件內容
       * @param callback 回調
       * @param <T>
       */
      public <T> void postFile(final Class<T> clazz,final String url,Header[] header,String name,String fileName,byte[] fileContent,final RequestDataCallback<T> callback){
          postFile(clazz,url,header,name,fileName,fileContent,callback,null);
      }
      
      
      /**
       * 上傳文件
       * @param clazz json對應類的類型
       * @param url 請求url
       * @param header 請求頭
       * @param name 名字
       * @param fileName 文件名
       * @param fileContent 文件內容
       * @param callback 回調
       * @param progressUIListener 回調上傳進度
       * @param <T>
       */
      public <T> void postFile(Class<T> clazz,final String url,Header[] header,String name,String fileName,byte[] fileContent,final RequestDataCallback<T> callback,ProgressUIListener progressUIListener) {
          add(url,postFile(url, header,name,fileName,fileContent,new HTTPCaller.MyHttpResponseHandler(clazz,url,callback),progressUIListener));
      }
      
      private Call postFile(String url, Header[] header,List<NameValuePair> form,HttpResponseHandler responseCallback,ProgressUIListener progressUIListener){
          try {
              MultipartBody.Builder builder = new MultipartBody.Builder();
              builder.setType(MultipartBody.FORM);
              MediaType mediaType = MediaType.parse("application/octet-stream");
      
              form.addAll(httpConfig.getCommonField());//添加公共字段
      
              for(int i=form.size()-1;i>=0;i--){
                  NameValuePair item = form.get(i);
                  if(item.isFile()){//上傳文件
                      File myFile = new File(item.getValue());
                      if (myFile.exists()){
                          String fileName = Util.getFileName(item.getValue());
                          builder.addFormDataPart(item.getName(), fileName,RequestBody.create(mediaType, myFile));
                      }
                  }else{
                      builder.addFormDataPart(item.getName(), item.getValue());
                  }
              }
      
              RequestBody requestBody;
              if(progressUIListener==null){//不需要回調進度
                  requestBody=builder.build();
              }else{//需要回調進度
                  requestBody = ProgressHelper.withProgress(builder.build(),progressUIListener);
              }
              Request.Builder requestBuider = new Request.Builder();
              requestBuider.url(url);
              requestBuider.post(requestBody);
              return execute(requestBuider, header, responseCallback);
          } catch (Exception e) {
              e.printStackTrace();
              Log.e(httpConfig.getTagName(),e.toString());
              if (responseCallback != null)
                  responseCallback.onFailure(-1, e.getMessage().getBytes());
          }
          return null;
      }
      
      private Call postFile(String url, Header[] header,String name,String filename,byte[] fileContent, HttpResponseHandler responseCallback,ProgressUIListener progressUIListener) {
          try {
              MultipartBody.Builder builder = new MultipartBody.Builder();
              builder.setType(MultipartBody.FORM);
              MediaType mediaType = MediaType.parse("application/octet-stream");
              builder.addFormDataPart(name,filename,RequestBody.create(mediaType, fileContent));
      
              List<NameValuePair> form = new ArrayList<>(2);
              form.addAll(httpConfig.getCommonField());//添加公共字段
              for (NameValuePair item : form) {
                  builder.addFormDataPart(item.getName(),item.getValue());
              }
      
              RequestBody requestBody;
              if(progressUIListener==null){//不需要回調進度
                  requestBody=builder.build();
              }else{//需要回調進度
                  requestBody = ProgressHelper.withProgress(builder.build(),progressUIListener);
              }
              Request.Builder requestBuider = new Request.Builder();
              requestBuider.url(url);
              requestBuider.post(requestBody);
              return execute(requestBuider, header,responseCallback);
          } catch (Exception e) {
              if (httpConfig.isDebug()) {
                  e.printStackTrace();
                  Log.e(httpConfig.getTagName(), e.toString());
              }
              if (responseCallback != null)
                  responseCallback.onFailure(-1, e.getMessage().getBytes());
          }
          return null;
      }
      

      增加下載文件的方法

      get請求跟post請求都有了,上傳文件就是post請求,繼續增加downloadFile方法用來下載文件,通用的MyHttpResponseHandler不能處理回調,又增加了DownloadFileResponseHandler類處理下載回調。

      public void downloadFile(String url, String saveFilePath, Header[] header, ProgressUIListener progressUIListener) {
              downloadFile(url,saveFilePath, header, progressUIListener,true);
          }
      
      public void downloadFile(String url,String saveFilePath, Header[] header,ProgressUIListener progressUIListener,boolean autoCancel) {
          if (checkAgent()) {
              return;
          }
          add(url,downloadFileSendRequest(url,saveFilePath, header, progressUIListener),autoCancel);
      }
      
      private Call downloadFileSendRequest(String url, final String saveFilePath, Header[] header, final ProgressUIListener progressUIListener){
          Request.Builder builder = new Request.Builder();
          builder.url(url);
          builder.get();
          return execute(builder, header, new HTTPCaller.DownloadFileResponseHandler(url,saveFilePath,progressUIListener));
      }
      
      public class DownloadFileResponseHandler implements Callback {
          private String saveFilePath;
          private ProgressUIListener progressUIListener;
          private String url;
      
          public DownloadFileResponseHandler(String url,String saveFilePath,ProgressUIListener progressUIListener){
              this.url=url;
              this.saveFilePath=saveFilePath;
              this.progressUIListener=progressUIListener;
          }
      
          @Override
          public void onFailure(Call call, IOException e) {
              clear(url);
              try {
                  printLog(url + " " + -1 + " " + new String(e.getMessage().getBytes(), "utf-8"));
              } catch (UnsupportedEncodingException encodingException) {
                  encodingException.printStackTrace();
              }
          }
      
          @Override
          public void onResponse(Call call, Response response) throws IOException {
              printLog(url + " code:" + response.code());
              clear(url);
      
              ResponseBody responseBody = ProgressHelper.withProgress(response.body(),progressUIListener);
              BufferedSource source = responseBody.source();
      
              File outFile = new File(saveFilePath);
              outFile.delete();
              outFile.createNewFile();
      
              BufferedSink sink = Okio.buffer(Okio.sink(outFile));
              source.readAll(sink);
              sink.flush();
              source.close();
          }
      }
      

      RequestDataCallback接口,封裝了三個方法,自己想要什么數據就去重寫對應的方法。

      public abstract class RequestDataCallback<T> {
          //返回json對象
          public void dataCallback(T obj) {
          }
      
          //返回http狀態和json對象
          public void dataCallback(int status, T obj) {
              dataCallback(obj);
          }
      
          //返回http狀態、json對象和http原始數據
          public void dataCallback(int status, T obj, byte[] body) {
              dataCallback(status, obj);
          }
      }
      

      還有Util公共類,有三個靜態方法。

      public class Util {
          /**
           * 獲取文件名稱
           * @param filename
           * @return
           */
          public static String getFileName(String filename){
              int start=filename.lastIndexOf("/");
      //        int end=filename.lastIndexOf(".");
              if(start!=-1){
                  return filename.substring(start+1,filename.length());
              }else{
                  return null;
              }
          }
      
          /**
           * 拼接公共參數
           * @param url
           * @param commonField
           * @return
           */
          public static String getMosaicParameter(String url, List<NameValuePair> commonField){
              if (TextUtils.isEmpty(url))
                  return "";
              if (url.contains("?")) {
                  url = url + "&";
              } else {
                  url = url + "?";
              }
              url += getCommonFieldString(commonField);
              return url;
          }
      
          private static String getCommonFieldString(List<NameValuePair> commonField){
              StringBuffer sb = new StringBuffer();
              try{
                  int i=0;
                  for (NameValuePair item:commonField) {
                      if(i>0){
                          sb.append("&");
                      }
                      sb.append(item.getName());
                      sb.append('=');
                      sb.append(URLEncoder.encode(item.getValue(),"utf-8"));
                      i++;
                  }
              }catch (Exception e){
      
              }
              return  sb.toString();
          }
      }
      

      源碼下載

      OkHttp封裝之后如何使用

      如果你想第一時間看我的后期文章,掃碼關注公眾號,每周不定期推送Android開發實戰教程文章...

            Android開發666 - 安卓開發技術分享
                   掃描二維碼加關注
      

      Android開發666

      posted @ 2017-08-31 18:42  安輝  閱讀(2372)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 性久久久久久| 精品国产亚洲一区二区三区| 少妇上班人妻精品偷人| 精品在免费线中文字幕久久| 国产亚洲精品成人aa片新蒲金| 色欲aⅴ亚洲情无码av蜜桃| 潘金莲高清dvd碟片| 91国内精品久久精品一本| 99久久国产综合精品女图图等你 | 呦系列视频一区二区三区 | 亚洲国产成熟视频在线多多| 久久人人97超碰精品| 激情亚洲专区一区二区三区| 真实单亲乱l仑对白视频| 久久伊99综合婷婷久久伊| 亚洲国产精品自产拍久久| 俺也来俺也去俺也射| 日韩一区二区三区无码a片| 国产午夜亚洲精品国产成人| 茶陵县| 亚洲AV日韩精品久久久久| 狠狠综合久久综合88亚洲| 两性午夜刺激性视频| 欧美精品18videosex性欧美| av中文字幕国产精品| 修文县| 久久99日韩国产精品久久99| 欧美日韩国产一区二区三区欧| 国产破外女出血视频| 人妻熟女一区无中文字幕| 成人午夜在线观看日韩| 麻豆国产AV剧情偷闻女邻居内裤 | 国产系列高清精品第一页| 国产午夜三级一区二区三| 亚洲一区二区三级av| 无码专区 人妻系列 在线| 最新国产AV最新国产在钱| 国产美女久久精品香蕉| 国产亚洲AV电影院之毛片| 久章草在线毛片视频播放| 免费无码又爽又刺激成人|