AsyncTask介紹

看上去修改後的connect()方法已經可用了,但是這種匿名線程的方式是存在缺陷的:第一,線程的開銷較大,如果每個任務都要創建一個線程,那麼應用程序的效率要低很多;第二,線程無法管理,匿名線程創建並啓動後就不受程序的控制了,如果有很多個請求發送,那麼就會啓動非常多的線程,系統將不堪重負。另外,前面已經看到,在新線程中更新UI還必須要引入handler,這讓代碼看上去非常臃腫。

       
爲了解決這一問題,OPhone1.5版本引入了AsyncTaskAsyncTask的特點是任務在主線程之外運行,而回調方法是在主線程中執行,這就有效地避免了使用Handler帶來的麻煩。閱讀AsyncTask的源碼可知,AsyncTask是使用java.util.concurrent 框架來管理線程以及任務的執行的,concurrent框架是一個非常成熟,高效的框架,經過了嚴格的測試。這說明AsyncTask的設計很好的解決了匿名線程存在的問題。

      AsyncTask
是抽象類,子類必須實現抽象方法doInBackground(Params... p) ,在此方法中實現任務的執行工作,比如連接網絡獲取數據等。通常還應該實現onPostExecute(Result r)方法,因爲應用程序關心的結果在此方法中返回。需要注意的是AsyncTask一定要在主線程中創建實例。AsyncTask定義了三種泛型類型 ParamsProgressResult

    * Params
啓動任務執行的輸入參數,比如HTTP請求的URL
    * Progress
後臺任務執行的百分比。
    * Result
後臺執行任務最終返回的結果,比如String

      AsyncTask
的執行分爲四個步驟,與前面定義的TaskListener類似。每一步都對應一個回調方法,需要注意的是這些方法不應該由應用程序調用,開發者需要做的就是實現這些方法。在任務的執行過程中,這些方法被自動調用。

    * onPreExecute()
當任務執行之前開始調用此方法,可以在這裏顯示進度對話框。
    * doInBackground(Params...)
此方法在後臺線程執行,完成任務的主要工作,通常需要較長的時間。在執行過程中可以調用publicProgress(Progress...)來更新任務的進度。
    * onProgressUpdate(Progress...)
此方法在主線程執行,用於顯示任務執行的進度。
    * onPostExecute(Result)
此方法在主線程執行,任務執行的結果作爲此方法的參數返回。

      PageTask
擴展了AsyncTask,在 doInBackground()方法中讀取網頁內容。PageTask的源代碼如下所示:

// 設置三種類型參數分別爲String,Integer,String  

    class PageTask extends AsyncTask<String, Integer, String> {  

  

        // 可變長的輸入參數,與AsyncTask.exucute()對應  

        @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);  

        }  

        @Override  

        protected void onPreExecute() {  

            // 任務啓動,可以在這裏顯示一個對話框,這裏簡單處理  

            message.setText(R.string.task_started);  

        }  

        @Override  

        protected void onProgressUpdate(Integer... values) {  

            // 更新進度  

            message.setText(values[0]);  

        }  

一、    }

 

發佈了15 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章