安卓进阶系列-08异步加载AsynsTask使用
生活随笔
收集整理的這篇文章主要介紹了
安卓进阶系列-08异步加载AsynsTask使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
利用AsyncTask和OkHttp進行API數據請求
- 背景
- 從安卓3.0開始,不允許在主線程和UI線程中進行網絡請求,因為可能會造成線程堵塞。
- 因此,只能在子線程進行網絡請求,出現了很多請求的方法,例如開啟子線程利用Message傳遞數據,或者OkHttp封裝了異步請求,會開啟新線程進行網絡請求。
- 本案例使用OkHttp(主要因為方便使用,比起HttpConnection和HttpClient效率不遑多讓,甚至仍有勝之)進行網絡請求,但是使用同步請求(不會開啟新的線程,因此會崩潰)。
- 本案例,處理網絡請求的方式為異步加載處理,利用AsyncTask開啟一個異步任務,任務返回結果并進行處理操作。
- 配置
- 添加okhttp和gson的依賴
- implementation 'com.squareup.okhttp3:okhttp:3.10.0'
- implementation 'com.google.code.gson:gson:2.8.2'
- 添加okhttp和gson的依賴
- 介紹
- 一般,將任務封裝為一個類并繼承AsyncTask<Params, Progress,Result>。繼承AsyncTask需要指定三個泛型參數。
- Params:啟動任務時輸入參數的類型,我這里傳入了一個URL路徑。
- Progress:后臺任務執行中返回進度值的類型,可以用來顯示進度。
- Result:后臺任務完成后返回結果的類型,我這里是一個自定義的Item。
- 如果你用的IDE是比較智能的如Android Studio,那么會提示實現相應的方法,其中doInBackGround是必須實現的,也是唯一一個子線程的方法。
- doInBackGround:必須重寫,子線程在這個方法里面進行耗時操作。(這個方法的進行在子線程中)
- onPreExecute:執行后臺耗時操作前被調用,通常在方法里面進行一些初始化的操作。
- onPostExecute:當doInBackground完成后,系統會自動調用這個方法,并且將doInBackground方法返回的值傳給該方法。
- onProgressUpdate:在doInBackground方法中調用publishProgress方法時,更新任務的執行進度后,會觸發這個方法。
- 一般,將任務封裝為一個類并繼承AsyncTask<Params, Progress,Result>。繼承AsyncTask需要指定三個泛型參數。
- 實戰使用
- 首先需要在manifest文件中添加網絡權限。
- 使用OkHttp+AsyncTask發送網絡請求并使用Gson解析API數據,渲染到界面的一個TextView上。
- 簡單編寫一個只含有name屬性的Bean類。
- 編寫Task類,繼承自AsyncTask并在后臺使用OkHttp進行網絡請求。請求的是自己編寫的一個API網站(API的WEB服務搭建這里不做敘述,請求得到的是json格式數據。)。
- 請求的數據結構
- package com.zc.testforasynctask;import android.content.Context;import android.os.AsyncTask;import android.util.Log;import android.widget.TextView;import android.widget.Toast;import com.google.gson.Gson;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;public class MyTask extends AsyncTask<String, String, Item> {private Context mContext;private TextView tv;public MyTask(Context mContext, TextView tv) {this.mContext = mContext;this.tv = tv;}@Overrideprotected void onPreExecute() {super.onPreExecute();Toast.makeText(mContext, "開始尋找網絡資源", Toast.LENGTH_SHORT).show();}private String baseUrl = "http://13.250.1.159:8000/api/";@Overrideprotected Item doInBackground(String... strings) {Item result;try {Thread.sleep(0b1111101000);OkHttpClient client = new OkHttpClient();String nowUrl = baseUrl + "merchants/" + strings[0] + ".json";Request request = new Request.Builder().url(nowUrl).build();Response response = client.newCall(request).execute();if (response.isSuccessful()){result = parseItemJsonObject(response.body().string());Log.i("msg", result.getName());}else {Toast.makeText(mContext, "無結果", Toast.LENGTH_SHORT).show();return null;}}catch (Exception e){Toast.makeText(mContext, "網絡連接異常", Toast.LENGTH_SHORT).show();return null;}return result;}@Overrideprotected void onPostExecute(Item item) {super.onPostExecute(item);if(item != null){tv.setText(item.getName());}else {tv.setText("數據解析為空");}}private Item parseItemJsonObject(String jsonData) {// 解析Json對象try {if (jsonData != null) {//創建一個Gson對象Gson gson = new Gson();Item item = gson.fromJson(jsonData,Item.class);return item;}else {return null;}}catch (Exception e){e.printStackTrace();return null;}}}
- 請求的數據結構
- 主活動進行事件綁定和點擊事件注冊
- 代碼見GitHub
- 效果展示
- 補充說明
- 具體代碼和環境配置見我的GitHub,歡迎star或者fork
- 歡迎指出優化之處
總結
以上是生活随笔為你收集整理的安卓进阶系列-08异步加载AsynsTask使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web开发-Django初识及实战
- 下一篇: 机器学习-分类之决策树原理及实战