android Okhttp3的簡單使用(親測可用,原始碼已貼出)
阿新 • • 發佈:2018-12-09
1.先在model中新增所需要的依賴,主要有:
compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.google.code.gson:gson:2.8.2'
2.Activity程式碼實現@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(1)父類activity
package com.mobile.administrator.appmine09.base; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; /** * Created by Administrator on 2018/9/11 0011. */ public abstract class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } protected abstract void initData(); protected abstract void initView(); protected abstract void showToast(String msg); protected abstract void runToUIThread(String dataStr, String showStr); }
(2)activity
package com.mobile.administrator.appmine09.activity; import android.Manifest; import android.os.Build; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.mobile.administrator.appmine09.R; import com.mobile.administrator.appmine09.base.BaseActivity; import com.mobile.administrator.appmine09.bean.ReasonBean; import com.mobile.administrator.appmine09.callback.LoadCallback; import com.mobile.administrator.appmine09.manager.Okhttp3Manager; import com.mobile.administrator.appmine09.utils.MyLogUtil; import java.io.IOException; import java.util.HashMap; import java.util.Map; import butterknife.BindView; import butterknife.ButterKnife; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; public class MainActivity extends BaseActivity implements View.OnClickListener { @BindView(R.id.tev_get_sync) TextView tevGetSync; @BindView(R.id.tev_get_async) TextView tevGetAsync; @BindView(R.id.tev_post_sync) TextView tevPostSync; @BindView(R.id.tev_post_async) TextView tevPostAsync; @BindView(R.id.tev_data) TextView tevData; private Okhttp3Manager manager; public static final String GET_URL = "http://v.juhe.cn/toutiao/index?type=歷史&key=d05b58fa6901ad9bed77a1ef08bd6ccb"; public static final String POST_URL = "http://v.juhe.cn/toutiao/index"; private String url2 = "https://baike.baidu.com/pic/%E6%AD%A6%E7%94%B0%E7%8E%B2%E5%A5%88/16824602/0/32fa828ba61ea8d3ec4ad9129e0a304e251f58bf?fr=lemma&ct=single#aid=0&pic=32fa828ba61ea8d3ec4ad9129e0a304e251f58bf"; private Map<String, String> map = new HashMap<>(); private ReasonBean reasonBean; private static final String TAG = MainActivity.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); initData(); initView(); } @Override protected void initData() { if (Build.VERSION.SDK_INT >= 23) { String[] mPermissionList = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CALL_PHONE, Manifest.permission.READ_LOGS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.SET_DEBUG_APP, Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.GET_ACCOUNTS, Manifest.permission.WRITE_APN_SETTINGS}; ActivityCompat.requestPermissions(this, mPermissionList, 123); } manager = Okhttp3Manager.getInstance(this); map.put("type", "娛樂"); map.put("key", "d05b58fa6901ad9bed77a1ef08bd6ccb"); } @Override protected void initView() { tevGetSync.setOnClickListener(this); tevGetAsync.setOnClickListener(this); tevPostSync.setOnClickListener(this); tevPostAsync.setOnClickListener(this); } @Override protected void showToast(String msg) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } /** * 請求返回的資料都是在子執行緒,要把它執行到主執行緒 * @param dataStr * @param showStr */ @Override protected void runToUIThread(final String dataStr, final String showStr) { runOnUiThread(new Runnable() { @Override public void run() { showToast(showStr); if (!"".equals(dataStr)) { reasonBean = manager.fromJson(1.0, dataStr, ReasonBean.class); MyLogUtil.i(TAG, "dataStr*****" + dataStr); MyLogUtil.i(TAG, "reasonBean.toString()*****" + reasonBean.toString()); tevData.setText(dataStr); } else { tevData.setText(dataStr); } } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tev_get_sync: manager.getSyncOkHttp(GET_URL, new LoadCallback() { @Override public void getSuccess(final String dataStr) { runToUIThread(dataStr, "請求成功!"); } @Override public void getFailed() { runToUIThread("", "請求成功!"); showToast("請求失敗!"); } }); break; case R.id.tev_get_async: manager.getAsyncOkHttp(GET_URL, map, new Callback() { @Override public void onFailure(Call call, IOException e) { runToUIThread("", "請求失敗!"); } @Override public void onResponse(Call call, Response response) throws IOException { runToUIThread(response.body().string(), "請求成功!"); } }); break; case R.id.tev_post_sync: manager.postSyncOkhttp(POST_URL, map, new LoadCallback() { @Override public void getSuccess(String dataStr) { runToUIThread(dataStr, "請求成功!"); } @Override public void getFailed() { runToUIThread("", "請求失敗!"); } }); break; case R.id.tev_post_async: manager.postAsyncOkhttp(POST_URL, map, new Callback() { @Override public void onFailure(Call call, IOException e) { runToUIThread("", "請求失敗!"); } @Override public void onResponse(Call call, Response response) throws IOException { runToUIThread(response.body().string(), "請求成功!"); } }); break; default: break; } } @Override protected void onDestroy() { super.onDestroy(); } }
3.Okhttp3程式碼實現&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.manager; import android.content.Context; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.mobile.administrator.appmine09.callback.LoadCallback; import com.mobile.administrator.appmine09.utils.MyLogUtil; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * Created by Administrator on 2018/9/8 0008. */ public class Okhttp3Manager { private OkHttpClient client; private static Okhttp3Manager manager; private Gson gson; private static final String TAG = Okhttp3Manager.class.getSimpleName(); /** * 單例模式,所以建構函式私有化 */ private Okhttp3Manager() { //建立OkHttpClient物件 client = new OkHttpClient.Builder() .connectTimeout(5 * 1000, TimeUnit.MILLISECONDS) //連結超時 .readTimeout(10 * 1000, TimeUnit.MILLISECONDS) //讀取超時 .writeTimeout(10 * 1000, TimeUnit.MILLISECONDS) //寫入超時 .build(); gson = new GsonBuilder().setVersion(1.0) .create(); } /** * 執行緒安全的單例模式,整個專案中只有一個okhttp3例項 * @param context * @return */ public static Okhttp3Manager getInstance(Context context) { if (manager == null) { synchronized (Okhttp3Manager.class) { if (manager == null) { manager = new Okhttp3Manager(); } } } return manager; } /** * 同步請求 寫了一個介面把值放入 */ public void getSyncOkHttp(String url, final LoadCallback loadCallback) { //呼叫ok的get請求 Request request = new Request.Builder() .get() .url(url) .build(); final Call call = client.newCall(request); //同步execute //同步請求 //同步是耗時的 //同步execute需要開啟子執行緒 new Thread(new Runnable() { @Override public void run() { try { Response response = call.execute(); if (response.isSuccessful()) { String string = response.body().string(); //呼叫者只需要實現provide方法就能拿到這個String了 loadCallback.getSuccess(string); } else { loadCallback.getFailed(); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** * get拼接傳值方法(非同步請求) * * @param url ?username=xxxx&password=xxx */ public void getAsyncOkHttp(String url, Map<String, String> map, Callback callback) { StringBuffer sb = new StringBuffer(); String string = ""; String result = ""; //當用戶傳入null或者傳了一個空的map if (map != null && !map.isEmpty()) { for (Map.Entry<String, String> entry : map.entrySet()) { if (sb == null) { // sb = new StringBuffer (); sb.append("?"); } else { //拼接好的網站去掉最後一個“&”符號 sb.append("&"); } sb.append(entry.getKey() + "=" + entry.getValue()); } } if (sb.toString() != null) { string = sb.toString(); MyLogUtil.i(TAG, string); result = url + string; MyLogUtil.i(TAG, result); } Request request = new Request.Builder() .get() //宣告我是get請求,如果不寫預設就是get .url(string == "" ? url : result)//宣告網站訪問的網址 .build();//建立Request Call call = client.newCall(request); //同步execute,非同步enqueue //這裡的同步是耗時的 //而且OK 也沒有為我們開啟子執行緒 // 如果你用同步方法的話,需要開啟子執行緒 call.enqueue(callback); } /** * Post請求(同步請求) * <p> * FormBody:用來提交一個不包涵檔案的引數 * 第 */ public void postSyncOkhttp(String url, Map<String, String> map, final LoadCallback loadCallback) { //上傳文字格式 資料的傳輸,區別於多媒體輸出 FormBody.Builder formbody = new FormBody.Builder(); if (map != null && !map.isEmpty()) { //上傳引數 for (String key : map.keySet()) { formbody.add(key, map.get(key)); } //建立請求體 FormBody body = formbody.build(); Request request = new Request.Builder() .post(body) .url(url) .build(); final Call call = client.newCall(request); //同步請求方式 //同步execute //同步請求 //同步是耗時的 //同步execute需要開啟子執行緒 new Thread(new Runnable() { @Override public void run() { try { Response response = call.execute(); if (response.isSuccessful()) { String string = response.body().string(); //呼叫者只需要實現provide方法就能拿到這個String了 loadCallback.getSuccess(string); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } else { //建立請求體 FormBody body = formbody.build(); Request request = new Request.Builder() .post(body) .url(url) .build(); final Call call = client.newCall(request); //同步請求方式 //同步execute //同步請求 //同步是耗時的 //同步execute需要開啟子執行緒 new Thread(new Runnable() { @Override public void run() { try { Response response = call.execute(); if (response.isSuccessful()) { String string = response.body().string(); //呼叫者只需要實現provide方法就能拿到這個String了 loadCallback.getSuccess(string); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } } /** * Post請求(非同步請求) * <p> * FormBody:用來提交一個不包涵檔案的引數 * 第 */ public void postAsyncOkhttp(String url, Map<String, String> map, Callback callBack) { //上傳文字格式 資料的傳輸,區別於多媒體輸出 FormBody.Builder formbody = new FormBody.Builder(); if (map != null && !map.isEmpty()) { //上傳引數 for (String key : map.keySet()) { formbody.add(key, map.get(key)); } //建立請求體 FormBody body = formbody.build(); Request request = new Request.Builder() .url(url) .post(body)//請求體 .build(); Call call = client.newCall(request); //非同步請求方式 call.enqueue(callBack); } else { //建立請求體 FormBody body = formbody.build(); Request request = new Request.Builder() .url(url) .post(body) .build(); Call call = client.newCall(request); //非同步請求方式 call.enqueue(callBack); } } /** * MultipartBody:用來提交包涵檔案的引數(非同步請求) * * @param path :路徑 * @param map :普通引數 * @param img :提交檔案的關鍵字 * @param imgPath :提交檔案的路徑 */ public void postFileOkhttp(String path, HashMap<String, String> map, String img, String imgPath, Callback callBack) { MultipartBody.Builder requestBody = new MultipartBody.Builder(); if (map != null && !map.isEmpty()) { //上傳引數 for (String key : map.keySet()) { requestBody.addFormDataPart(key, map.get(key)); } File file = new File(imgPath); requestBody.addFormDataPart(img, file.getPath() , RequestBody.create(MediaType.parse("image/png"), file)); Request request = new Request.Builder() .post(requestBody.build()) .url(path) .build(); Call call = client.newCall(request); call.enqueue(callBack); } else { File file = new File(imgPath); requestBody.addFormDataPart(img, file.getPath() , RequestBody.create(MediaType.parse("image/png"), file)); Request request = new Request.Builder() .post(requestBody.build()) .url(path) .build(); Call call = client.newCall(request); call.enqueue(callBack); } } /** * 用於將指定的Object物件序列化成相應的JSON資料 * * @param version * @param object * @return */ public String toJson(double version, Object object) { return gson.toJson(object); } /** * 用於將JsonElement物件(可以是JsonObject、JsonArray等)轉換成JSON資料 * * @param version * @param jsonElement * @return */ public String toJson(double version, JsonElement jsonElement) { String str = gson.toJson(jsonElement); return str; } /** * @param jsonStr * @param classOfT * @param <T> * @return */ public <T> T fromJson(double version, String jsonStr, Class<T> classOfT) { return gson.fromJson(jsonStr, classOfT); } }
4.自定義介面回撥程式碼實現&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.callback; /** * Created by ${周康} on ${Study}. */ public interface LoadCallback { void getSuccess(String dataStr); void getFailed(); }
5.實體類程式碼實現&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.bean; import java.util.List; /** * Created by Administrator on 2018/9/9 0009. */ public class ReasonBean { private String reason; private ResultBean result; private int error_code; public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } public ResultBean getResult() { return result; } public void setResult(ResultBean result) { this.result = result; } public int getError_code() { return error_code; } public void setError_code(int error_code) { this.error_code = error_code; } public static class ResultBean { private String stat; private List<DataBean> data; public String getStat() { return stat; } public void setStat(String stat) { this.stat = stat; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { private String uniquekey; private String title; private String date; private String category; private String author_name; private String url; private String thumbnail_pic_s; private String thumbnail_pic_s02; private String thumbnail_pic_s03; public String getUniquekey() { return uniquekey; } public void setUniquekey(String uniquekey) { this.uniquekey = uniquekey; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getThumbnail_pic_s() { return thumbnail_pic_s; } public void setThumbnail_pic_s(String thumbnail_pic_s) { this.thumbnail_pic_s = thumbnail_pic_s; } public String getThumbnail_pic_s02() { return thumbnail_pic_s02; } public void setThumbnail_pic_s02(String thumbnail_pic_s02) { this.thumbnail_pic_s02 = thumbnail_pic_s02; } public String getThumbnail_pic_s03() { return thumbnail_pic_s03; } public void setThumbnail_pic_s03(String thumbnail_pic_s03) { this.thumbnail_pic_s03 = thumbnail_pic_s03; } @Override public String toString() { return "DataBean{" + "uniquekey='" + uniquekey + '\'' + ", title='" + title + '\'' + ", date='" + date + '\'' + ", category='" + category + '\'' + ", author_name='" + author_name + '\'' + ", url='" + url + '\'' + ", thumbnail_pic_s='" + thumbnail_pic_s + '\'' + ", thumbnail_pic_s02='" + thumbnail_pic_s02 + '\'' + ", thumbnail_pic_s03='" + thumbnail_pic_s03 + '\'' + '}'; } } @Override public String toString() { return "ResultBean{" + "stat='" + stat + '\'' + ", data=" + data + '}'; } } @Override public String toString() { return "ReasonBean{" + "reason='" + reason + '\'' + ", result=" + result + ", error_code=" + error_code + '}'; } }
6.工具類程式碼實現&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
package com.mobile.administrator.appmine09.utils; import android.util.Log; /** * Created by Administrator on 2018/4/26 0026. */ public class MyLogUtil { //規定每段顯示的長度 private static int LOG_MAXLENGTH = 2000; public static void i(String TAG, String msg) { int strLength = msg.length(); int start = 0; int end = LOG_MAXLENGTH; for (int i = 0; i < 100; i++) { //剩下的文字還是大於規定長度則繼續重複擷取並輸出 if (strLength > end) { Log.i(TAG + i, msg.substring(start, end)); start = end; end = end + LOG_MAXLENGTH; } else { Log.i(TAG, msg.substring(start, strLength)); break; } } } }
7.佈局檔案程式碼實現&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.mobile.administrator.appmine09.activity.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:layout_gravity="center"> <TextView android:id="@+id/tev_get_sync" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:gravity="center" android:layout_gravity="center" android:text="getSync" android:textColor="@color/colorPrimary" android:textSize="20sp" /> <TextView android:id="@+id/tev_get_async" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:gravity="center" android:layout_gravity="center" android:text="getASync" android:textColor="@color/colorPrimary" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:layout_gravity="center"> <TextView android:id="@+id/tev_post_sync" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:gravity="center" android:layout_gravity="center" android:text="postSync" android:textColor="@color/colorPrimary" android:textSize="20sp" /> <TextView android:id="@+id/tev_post_async" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:gravity="center" android:layout_gravity="center" android:text="postASync" android:textColor="@color/colorPrimary" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="5"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/tev_data" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textColor="@color/colorPrimary" android:textSize="18sp" /> </ScrollView> </LinearLayout> </LinearLayout>
8.最後別忘了新增許可權&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
<uses-permission android:name="android.permission.INTERNET"/>