Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android線程操作對象AsyncTask線程機制

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

編輯:關於android開發

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


 簡單的說,一個程序只有一個主線程,可以有多個主線程。在Android世界中也是這樣,Android屬於單線程模型,耗時操作必須放在非主線程中執行,故而谷歌為了方便我們使用線程,為我們提供一個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 = "https://www.baidu.com/img/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中添加一個網絡訪問權限。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved