okhttp3為一個網路通訊套件,能夠快速實作出post.get.put等功能。
首先先加入此套件包:build.gradle(app)
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
加入網路權限:manifests
<uses-permission android:name="android.permission.INTERNET" />
這樣子就準備完成了。
首先先來了解execute與enqueue的差異:
execute:同步執行,可以用在背景執行緒中,當完成一個任務時,才繼續執行下一個任務,會比較好控管流程;使用Response接收回應狀態。
enqueue:非同步執行,適合用在主執行緒中,會自動產生一個新執行緒,不會卡住畫面,當收到回應需要更新畫面時,記得要切換回主執行緒(runOnUiThread);使用Callback接收回應狀態。
接下來是功能使用的部分:
取得伺服器JSON資料(POST):
OkHttpClient client = new OkHttpClient(); //這邊設定為接收JSON MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); //帶在Body給伺服器的資料 JSONObject data = new JSONObject(); data.put("idNumber", "0123456789"); data.put("password", "987654321"); //將資料放進Body中 RequestBody requestBody = RequestBody.create(data.toString(), mediaType); Request request = new Request.Builder() .url("http://192.168.1.1")//目標網址 .post(requestBody) .build(); //使用非同步執行 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Call call, final IOException e) { // Handle the error 失敗訊息 e.printStackTrace(); } @Override public void onResponse(final Call call, final Response response) throws IOException { //注意:response.body()只能讀取一次,所以要重複使用的話必須另外存下來 String responseString = response.body().string(); int responseCode = response.code(); LogUtil.d("onResponse", responseCode + ""); LogUtil.d("onResponse", responseString); switch (responseCode){ case 200: //資料處理 break; } } });
上傳檔案(put):
OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("multipart/form-data");//這邊設定為multipart/form-data RequestBody requestBody = RequestBody.create(filesUpload[i], mediaType);//將檔案放入Body中 MultipartBody multipartBody = new MultipartBody.Builder() .setType(mediaType) .addFormDataPart("file", filesUpload[i].getName(), requestBody) .build(); Request request = new Request.Builder() .url("http://127.0.0.1/upload")//上傳網址 .addHeader("Auth","123456")//可以帶一些認證 .put(multipartBody)//使用put上傳 .build(); //執行上傳 //使用非同步執行 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Call call, final IOException e) { // Handle the error 失敗訊息 e.printStackTrace(); } @Override public void onResponse(final Call call, final Response response) throws IOException { if (!response.isSuccessful()) {//如果response code介於200-300之間就是成功 // Handle the error 上傳失敗訊息 LogUtil.e("onResponse", response.toString()); } // Upload successful 上傳成功 LogUtil.e("onResponse-successful", response.toString()); } });
如果想用同步方式執行(execute),可以這樣子寫:
try { Response response = client.newCall(request).execute(); if(response.isSuccessful()){ //上傳成功 }else{ //上傳失敗 } } catch (IOException e) { e.printStackTrace(); }
OkHttpClient的設定:
client = new OkHttpClient.Builder() //設定連線超時 .connectTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build();
Log顯示 Interceptor功能:
很好用的Log列印功能,會印出每次的連線詳細資訊,方便我們觀看狀況。
加入此套件包:build.gradle(app)
implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0'
注意:interceptor的版本必須跟上面的okhttp版本一樣,才能正常使用
然後在OkHttpClient加入Interceptor:
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC)) .build();
這樣在網路連線時,就會顯示類似以下資料:
I/okhttp.OkHttpClient: --> PUT http://127.0.0.1:8085/v1/devices (49371363-byte body) I/okhttp.OkHttpClient: <-- 204 No Content http://127.0.0.1:8085/v1/devices (123ms, 0-byte body)
這樣就可以讓我們更清楚連線過程中發生了什麼事情!
Kotlin中的用法:
一般GET:
val client = OkHttpClient() val request = Request.Builder() .url("https//xxxxx.nnn") .addHeader("Authorization", "自己的驗證訊息") .build() //執行GET client.newCall(request).enqueue(object : Callback { //通常是網路連線錯誤的情況 override fun onFailure(call: Call, e: IOException) { e.printStackTrace() runOnUiThread {//因為在執行緒中,所以要用runOnUiThread來更新UI畫面 Toast.makeText(this@MainActivity, "請檢查網路連線", Toast.LENGTH_LONG).show() } } //收到回覆區域 override fun onResponse(call: Call, response: Response) { var responseString = response.body?.string() val responseCode = response.code LogUtil.d("onResponse", responseString) //進行自己的判斷、下一步 runOnUiThread { when (responseCode) { 200 -> { } 404 -> { } 500 -> { } else -> { } } } } })
POST用法:
//要POST的訊息 val userProfile = JSONObject() userProfile.put("email", "xxxxxxx") userProfile.put("name", "nnnnn") userProfile.put("phone", "09123456") //將JSON轉換為RequestBody val requestBody = userProfile.toString().toRequestBody() val client = OkHttpClient() val request = Request.Builder() .url("https//xxxxx.nnn") .method("POST", requestBody)//將RequestBody帶進POST中 .addHeader("Authorization", "自己的驗證訊息") .build() //執行 跟GET一樣 client.newCall(request).enqueue(object : Callback { //通常是網路連線錯誤的情況 override fun onFailure(call: Call, e: IOException) { e.printStackTrace() runOnUiThread {//因為在執行緒中,所以要用runOnUiThread來更新UI畫面 Toast.makeText(this@MainActivity, "請檢查網路連線", Toast.LENGTH_LONG).show() } } //收到回覆區域 override fun onResponse(call: Call, response: Response) { var responseString = response.body?.string() val responseCode = response.code LogUtil.d("onResponse", responseString) //進行自己的判斷、下一步 runOnUiThread { when (responseCode) { 200 -> { } 404 -> { } 500 -> { } else -> { } } } } })
-待續-
發佈留言