使用AsyncTask實現非同步操作
阿新 • • 發佈:2018-11-17
一、更新ui元件的方法
1、使用Handlers實現執行緒之間的通訊
2、Activity.runOnUiThread(Runnable)
3、View.post(Runnable)
4、View.postDelayed(Runnable,long)
5、使用非同步操作AsyncTask
二、AsyncTask<Params,Progress,Result>是一個抽象類,通常繼承AsyncTask時需要指定如下的三個泛型引數。
1、Params啟動任務時輸入的引數型別
2、Progress後臺任務完成的進度型別
3、Result後臺任務完成返回的結果型別
三、根據需要實現AsyncTask的四個方法
1、doInBackground(Params...)該方法就是在後臺完成任務,呼叫publishProgress方法更新任務執行進度
2、onPostExecute(Result result) 當doInBackground(Params...)完成後,系統自動呼叫
3、onPreExecute() 該方法通常會完成一些初始化的準備工作,比如介面顯示進度條
4、onProgressUpdate當調在doInBackground中呼叫publishProgress時,觸發該方法
四、AsyncTask子類的例項,呼叫execute()方法,開始執行耗時操作,其中的四個方法都應該由系統自動呼叫
五、使用非同步操作任務執行下載任務
1、xml檔案
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="開始下載" android:onClick="download" android:layout_gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/text1"/> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="phone" /> </LinearLayout> </ScrollView>
2、activity
public class AsyncTaskActivity1 extends AppCompatActivity { private TextView text1; protected void onCreate(Bundle saveInstanceSate) { super.onCreate(saveInstanceSate); setContentView(R.layout.async_task); text1=findViewById(R.id.text1); } public void download(View view) throws MalformedURLException { DownTask downTask=new DownTask(this); //呼叫execute()方法開始執行非同步操作 downTask.execute(new URL("https://luna.58.com/m/autotemplate?city=cd&creativeid=119&utm_source=link&spm=m-39558317773073-ms-f-801.mjh_daquanmingzhan01")); } //AsyncTask<Params,Progress,Result> //Params:啟動後臺執行任務輸入的引數 Progress:後臺任務完成的進度值的型別 Result:後臺執行任務完成後返回的結果型別 class DownTask extends AsyncTask<URL,Integer,String>{ //URL:為啟動後臺執行任務輸入的引數 Integer:後臺任務完成的進度值的型別 String:後臺執行任務完成後返回的結果型別 ProgressDialog dialog; //定義記錄已經讀取的行數 int hasRead=0; Context mContext; public DownTask(Context mContext) { this.mContext = mContext; } //(完成後臺下載)該方法後臺執行緒將要完成任務,呼叫publishProgress方法更新任務執行進度 @Override protected String doInBackground(URL... urls) { StringBuilder sb=new StringBuilder(); try{ URLConnection conn=urls[0].openConnection(); //將conn獲取的inputStream包裝為BufferedReader BufferedReader reader=new BufferedReader(new InputStreamReader(conn.getInputStream())); String line=null; while ((line=reader.readLine())!=null){ sb.append(line+"\n"); hasRead++; //此方法更新任務的執行進度 publishProgress(hasRead); } return sb.toString(); /*OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://www.taobao.com") .build(); Response response = client.newCall(request).execute(); String responseData = response.body().string(); return responseData;*/ } catch (IOException e) { e.printStackTrace(); } return null; } //(在完成下載後將網頁的程式碼顯示)在doInBackground(URL... urls)完成後,系統自動呼叫該方法,並將doInBackground(URL... urls)的返回值床底給這個方法 protected void onPostExecute(String result){ text1.setText(result); dialog.dismiss(); } //(開始下載前顯示一個進度條)該方法通常會完成一些初始化的準備工作,比如介面顯示進度條,將在後臺執行費時操作之前呼叫 protected void onPreExecute(){ dialog=new ProgressDialog(mContext); dialog.setTitle("任務正在進行"); dialog.setMessage("任務正在進行中,敬請等待..."); dialog.setCancelable(false); dialog.setMax(202); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setIndeterminate(false); dialog.show(); } //(更新進度條)當調在doInBackground中呼叫publishProgress時,觸發該方法 protected void onProgressUpdate(Integer... values){ text1.setText("已經讀取到【"+values[0]+"】行!"); dialog.setProgress(values[0]); } } }