安卓非同步任務(2)

來源:互聯網
上載者:User

標籤:des   android   http   io   os   ar   使用   java   strong   

1、使用非同步任務載入網路上的圖片

我們可以開啟這個網址:http://img1.3lian.com/img2011/07/20/05.jpg可以看到一副很好看的圖片,我們就要把這個圖片顯示出來,首先,還是先要布局,我們要顯示一幅圖片,所以我們的布局中需要一個ImageView,布局很簡單,一個ImageView就可以了:

  

 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent">
6 <ImageView
7 android:id="@+id/img"
8 android:scaleType="fitXY"
9 android:layout_width="match_parent"
10 android:layout_height="match_parent"/>
11 </LinearLayout>

 之後我們要寫一個Activity顯示這個圖片,不過要載入網路上的圖片,我們需要從一個URL的流中擷取這個圖片,所以我們要寫一個方法來擷取這張圖片:

  

1 public Drawable loadImages(String url) { 
2 try {
3 return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
4 }
5 catch (IOException e) {
6 e.printStackTrace();
7 }
8 return null;
9 }

  從URL中開啟流,強制轉換成InputStream,然後從流中拿到Drawable。

  既然可以擷取圖片了,我們要考慮一個問題,如果圖片很大,載入的很慢怎麼辦,我們豈不是要等很久?不要緊,這時候我們就可以用非同步任務了。

  首先我們要寫一個內部類,這個類部類是繼承自非同步任務的,需要重載裡面的doBackGround方法:

  

 1  private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
2
3 @Override
4 protected Drawable doInBackground (Void... params) {
5 String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
6 return loadImages(url);
7 }
8
9 @Override
10 protected void onPostExecute (Drawable result) {
11 super.onPostExecute(result);
12 mDialog.dismiss();
13 mImage.setImageDrawable(result);
14 }
15
16 @Override
17 protected void onPreExecute () {
18 super.onPreExecute();
19 mDialog.show();
20 }
21 }

 首先看這個方法:onPreExecute()這個方法是在doInBackGround前面執行。我們把這個方法寫出來,我們需要在擷取圖片之前等待的時間裡,寫一個progressDialog,顯示出來,提示使用者,目前正在載入圖片,需要等待一段時間。同時在後台操作doBackGround運行。

  在doBackGround完成之後就會執行onPostExecute(Drawable result)方法,看這個方法就知道,必須在doBackGround完成之後,把得到的結果Drawable作為參數傳到onPostExecute方法裡面去,執行這個方法就表示已經載入完了,我們需要將progressDialog消失掉,然後把圖片顯示出來就可以了,整個過程很簡單。

  看下整個Activity的代碼:

  

 1 package com.test.asyntask;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.URL;
6
7 import android.app.Activity;
8 import android.app.ProgressDialog;
9 import android.graphics.drawable.Drawable;
10 import android.os.AsyncTask;
11 import android.os.Bundle;
12 import android.widget.ImageView;
13
14 import com.test.R;
15
16 public class AsynTask extends Activity {
17
18 private ImageView mImage;
19 private ProgressDialog mDialog;
20
21 @Override
22 protected void onCreate (Bundle savedInstanceState) {
23 super.onCreate(savedInstanceState);
24 setContentView(R.layout.asyn_task);
25
26 mDialog = new ProgressDialog(this);
27 mDialog.setTitle("請稍等");
28 mDialog.setMessage("正在載入...");
29
30 mImage = (ImageView) findViewById(R.id.img);
31 new ImageAsynTask().execute();
32 }
33
34 private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
35
36 @Override
37 protected Drawable doInBackground (Void... params) {
38 String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
39 return loadImages(url);
40 }
41
42 @Override
43 protected void onPostExecute (Drawable result) {
44 super.onPostExecute(result);
45 mDialog.dismiss();
46 mImage.setImageDrawable(result);
47 }
48
49 @Override
50 protected void onPreExecute () {
51 super.onPreExecute();
52 mDialog.show();
53 }
54 }
55
56 @Override
57 protected void onDestroy () {
58 super.onDestroy();
59 mDialog.dismiss();
60 }
61
62 public Drawable loadImages(String url) {
63 try {
64 return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
65 }
66 catch (IOException e) {
67 e.printStackTrace();
68 }
69 return null;
70 }
71 }

 運行一下,看下效果:

  1.顯示progressDialog的時候,在載入圖片但是圖片還沒有載入出來的時候:

  

另外需要注意的是,需要在manifest裡面加入連結網路的許可權:

  

1 <uses-permission android:name="android.permission.INTERNET"/>

  另外在onDestory()的時候要把progressDialog dismiss掉,不讓在退出應用程式的時候會報錯。

2、按返回鍵暫停非同步任務

使用AsynTask非同步任務處理耗時操作(work)時,通常會增加ProgressDialog進度條來顯示等待操作(或載入進度)。

此時按返回鍵,因為焦點在ProgressDialog上,ProgressDialog捕獲返回鍵操作,而Activity是不響應返回鍵操作的。

如果你想實現,當進行耗時操作時(ProgressDialog正在顯示),按返回鍵,結束當前work操作。

你需要注意ProgressDialog的設定:

progress_dialog.setCancelable(true);//響應取消操作,這裡如果設定false,按返回鍵ProgressDialog也不消失。
progress_dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
      // TODO Auto-generated method stub

        AsynTask.this.cancle(true);//執行非同步線程取消操作
   }
});

同時注意,AsynTask執行cancele()操作後,相應的方法是如何執行。

You can stop a running task with cancel(true). A cancel will let the task finish its doInBackground but will never call onPostExecute. You could interrupt your background routine by checking isCanceled() and so return earlier since the task was killed.

參考:http://stackoverflow.com/questions/8209035/android-stop-asynctask-when-back-button-is-pressed-and-return-to-previous-acti

安卓非同步任務(2)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.