Android線程操作對象AsyncTask線程機制

來源:互聯網
上載者:User

 簡單的說,一個程式只有一個主線程,可以有多個主線程。在Android世界中也是這樣,Android屬於單執行緒模式,耗時操作必須放在非主線程中執行,故而Google為了方便我們使用線程,為我們提供一個AsyncTask多線程操作對象。

   對於Android使用線程還有一點需要特別注意,哪就是Android不允許在子線程中更新UI,相信很多初學者一定遇到過這個問題,這個怎麼解決呢?在Activity中,我們可以通過
   new Thread(new Runnable() {  @Override  public void run() {  Log.v("abc", "子線程執行");  runOnUiThread(new Runnable() {  @Override  public void run() {  Log.v("abc", "返回主線程執行");  }  });  }  }).start();
   來實現我們的效果,不過有一點需要注意的是,在Fragement中,runOnUiThread()不能使用,所以大家在使用時稍微注意一下即可。當然了Android中我們還可以通過Handler+Messager來完成多線程操作,對於這裡個的使用,在之前的部落格中已經為大家介紹,就不在贅述,下面我們開始介紹本篇的重點:AsyncTask的使用。
   AsyncTask<Parans, Progress, Result>是一個抽象類別,我們需要首先實現這個抽象類別,然後才能使用,對於它的三個參數:Parans:啟動任務時輸入的參數類型;progress:背景工作執行中傳回值的類型;Result:後台執行任務完成後返回的結果類型。
   構建AsyncTask子類的回調方法:1、doInBackground:必須重寫,非同步執行後台線程將要完成的任務; 2、onPreExecute:執行後台耗時操作前被調用,通過使用者完成一些初始化操作;3、onPostExecute:當doInBackground()完成之後,系統會自動調用,並將doInBackground()執行後的傳回值,傳遞給onPostExecute()方法,簡單來說就是,doInBackground()完成耗時操作,結果交個onPostExecute()方法更新UI;4、onProgressUpdate:在doInBackground()方法中,調用publishProgress()方法,更新任務的執行進度後,就會觸發該方法。
   說了這麼多,相信你心中還有一定的疑惑,下面我們通過兩個簡單的Android小程式,為大傢具體介紹一下AsyncTask的使用方法:
   a、AsyncTask中是個抽象方法的執行順序:
   1、建立一個AsyncTask子類對象:
   public class MyAsyncTask extends AsyncTask<Void, Void, Void> {  @Override  protected void onPreExecute() {  super.onPreExecute();  Log.v("abc", "onPreExecute");  }  @Override  protected Void doInBackground(Void... arg0) {  Log.v("abc", "doInBackground");  publishProgress(arg0);  return null;  }  @Override  protected void onPostExecute(Void result) {  super.onPostExecute(result);  Log.v("abc", "onPostExecute");  }  @Override  protected void onProgressUpdate(Void... values) {  super.onProgressUpdate(values);  Log.v("abc", "onProgressUpdate");  }  }
   2、在MainActivity中調用給子線程,進行執行:
   public class MainActivity extends Activity {  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  new MyAsyncTask().execute();//啟動執行  }
   3、執行後列印的log日誌:
   Android線程操作對象AsyncTask線程機制
   通過這個日誌資訊,是不是解決了你心中的疑惑,下面我們看一個使用AsyncTask載入網狀圖片的例子。
   b、載入網狀圖片:
   1、首先建立一個承載Activity布局檔案的xml:
   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:layout_margin="10dp"  tools:context=".MainActivity" >  <ImageView  android:id="@+id/img"  android:layout_width="match_parent"  android:layout_height="match_parent"  />  <ProgressBar  android:id="@+id/progressbar"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:visibility="gone"  android:layout_centerInParent="true"  />  </RelativeLayout>
   布局檔案很簡單,就是一個ImageView+ProgressBar,在載入ImageView是我們通過ProgressBar來提醒使用者等待。
   2、建立我們的Activity對象
   public class AsyncTaskImager extends Activity {  private ProgressBar pb;  private ImageView image;  private static final String url = "bdlogo.png";  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.imager);  init();  new ImageAsyncTask().execute(url);  }  private void init() {  pb = (ProgressBar) findViewById(R.id.progressbar);  image = (ImageView) findViewById(R.id.img);  }  class ImageAsyncTask extends AsyncTask<String, Void, Bitmap>{  @Override  protected void onPreExecute() {  super.onPreExecute();  pb.setVisibility(View.VISIBLE);  }  @Override  protected Bitmap doInBackground(String... params) {  Bitmap bitmap = null;  URLConnection conn = null;  String url = params[0];  try {  conn = new URL(url).openConnection();  InputStream in = conn.getInputStream();  BufferedInputStream bis = new BufferedInputStream(in);  bitmap = BitmapFactory.decodeStream(bis);  } catch (MalformedURLException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }  return bitmap;  }  @Override  protected void onPostExecute(Bitmap result) {  super.onPostExecute(result);  pb.setVisibility(View.GONE);  image.setImageBitmap(result);  }  }  }
   到這裡我們的大功已經基本完成了,最後不要忘記在AndroidManifest.xml中進行一下聲明。
   3、添加網路操作許可權:
   <uses-permission android:name="android.permission.INTERNET"/>  因為我們需要使用到網路連接,所以我們需要在AndroidManifest.xml中添加一個網路存取權限。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.