Android AsynTask更新主介面

來源:互聯網
上載者:User

標籤:

    雖然今天禮拜六還在加班,但是在等介面,所以還是有很多時間來自己學點東西的,所以就接著昨天的來。今天繼續學的是不通過主線程來更新主線程的介面的問題。

  昨天是用的開啟線程調用Handler來更新線程,那個效果用的方面比較廣闊,那麼我們還有幾種方法將耗時的代碼剝離出來不在主線程裡面執行,然後通過各種方法來更新UIThread .今天學到的是利用AsynTask來更新主介面的空間。

  然後我們先來說說AsynTask:

  AsynTask:Asynchronous Task(非同步任務)

使用過AsyncTask 的同學都知道一個非同步載入資料最少要重寫以下這兩個方法:

  • doInBackground(Params…) 後台執行,比較耗時的操作都可以放在這裡。注意這裡不能直接操作UI。此方法在後台線程執行,完成任務的主要工作,通常需要較長的時間。在執行過程中可以調用publicProgress(Progress…)來更新任務的進度。
  • onPostExecute(Result)  相當於Handler 處理UI的方式,在這裡面可以使用在doInBackground 得到的結果處理操作UI。 此方法在主線程執行,任務執行的結果作為此方法的參數返回

有必要的話你還得重寫以下這三個方法,但不是必須的:

  • onProgressUpdate(Progress…)   可以使用進度條增加使用者體驗度。 此方法在主線程執行,用於顯示任務執行的進度。
  • onPreExecute()        這裡是終端使用者調用Excute時的介面,當任務執行之前開始調用此方法,可以在這裡顯示進度對話方塊。
  • onCancelled()             使用者調用取消時,要做的操作

使用AsyncTask類,以下是幾條必須遵守的準則:

  • Task的執行個體必須在UI thread中建立;
  • execute方法必須在UI thread中調用;
  • 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法;
  • 該task只能被執行一次,否則多次調用時將會出現異常;

  好了繼續以往風格,再說需求:

    需求是在介面通過輸入一個完整的網址然後通過點擊按鈕來訪問網路,在訪問的時候展示一個進度條,然後將得到的網頁代碼顯示在主介面上。

  

然後上代碼:TestAsynTaskActivity

package com.example.testandroid;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View.OnClickListener;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.util.ArrayList;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.os.AsyncTask;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class TestAsynTaskActivity extends Activity implements OnClickListener {    private TextView message;    private Button open;    private EditText url;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_test_asyn_task);        message = (TextView) findViewById(R.id.show);        url = (EditText) findViewById(R.id.url);        open = (Button) findViewById(R.id.open);        open.setOnClickListener(this);    }        private void connect() {        PageTask task = new PageTask(this);        task.execute(url.getText().toString());    }    class PageTask extends AsyncTask<String, Integer, String> {        // 可變長的輸入參數,與AsyncTask.exucute()對應        ProgressDialog pdialog;        public PageTask(Context context) {            pdialog = new ProgressDialog(context, 0);            pdialog.setButton("cancel", new DialogInterface.OnClickListener() {                public void onClick(DialogInterface dialog, int i) {                    dialog.cancel();//這個方法過時了。                }            });            pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {                public void onCancel(DialogInterface dialog) {                    finish();                }            });            pdialog.setCancelable(true);            pdialog.setMax(100);            pdialog.setTitle("正在請求網路!");            pdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);            pdialog.show();        }        @Override        protected String doInBackground(String... params) {            try {                HttpClient client = new DefaultHttpClient();                // params[0]代表串連的url                HttpGet get = new HttpGet(params[0]);                HttpResponse response = client.execute(get);                HttpEntity entity = response.getEntity();                long length = entity.getContentLength();                InputStream is = entity.getContent();                String s = null;                if (is != null) {                    ByteArrayOutputStream baos = new ByteArrayOutputStream();                    byte[] buf = new byte[128];                    int ch = -1;                    int count = 0;                    while ((ch = is.read(buf)) != -1) {                        baos.write(buf, 0, ch);                        count += ch;                        if (length > 0) {                            // 如果知道響應的長度,調用publishProgress()更新進度                            publishProgress((int) ((count / (float) length) * 100));                        }                        // 讓線程休眠100ms                        Thread.sleep(100);                    }                    s = new String(baos.toByteArray());                }                // 返回結果                return s;            } catch (Exception e) {                e.printStackTrace();            }            return null;        }        @Override        protected void onCancelled() {            super.onCancelled();        }        @Override        protected void onPostExecute(String result) {            // 返回HTML頁面的內容            message.setText(result);            pdialog.dismiss();        }        @Override        protected void onPreExecute() {            // 任務啟動,可以在這裡顯示一個對話方塊,這裡簡單處理            message.setText("正在更新。。。");        }        @Override        protected void onProgressUpdate(Integer... values) {            // 更新進度            System.out.println("" + values[0]);            message.setText("" + values[0]);            pdialog.setProgress(values[0]);        }    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.open:            connect();            break;        default:            break;        }    }}

下面是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" >    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent" >        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="match_parent" >            <TextView                android:id="@+id/show"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_margin="15dp"                android:background="@drawable/shape1"                android:hint="@string/tv_hint" />            <EditText                android:id="@+id/url"                android:layout_width="200dp"                android:layout_height="wrap_content"                android:layout_below="@id/show"                android:layout_marginLeft="15dp"                android:layout_marginTop="15dp"                android:background="@null"                android:hint="在這裡輸入網址" />            <Button                android:id="@+id/open"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_below="@id/url"                android:layout_marginLeft="15dp"                android:layout_marginTop="15dp"                android:background="@drawable/shape2"                android:text="開啟網頁"                android:textColor="#FFFFFF"                android:textSize="20dp" />        </RelativeLayout>    </ScrollView></RelativeLayout>

最後,因為是要訪問網路,我們要記得在manifest檔案裡面加入INTERNET許可權。好啦簡單的一個AsynTask的實現就完成了!

 

Android AsynTask更新主介面

聯繫我們

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