1. 程式人生 > >使用AsyncTask完成進度條載入

使用AsyncTask完成進度條載入

AsyncTask

AsyncTask和Handler對比

AsyncTask實現的原理,和適用的優缺點

AsyncTask,是android提供的輕量級的非同步類,可以直接繼承AsyncTask,在類中實現非同步操作,並提供介面反饋當前非同步執行的程度(可以通過介面實現UI進度更新),最後反饋執行的結果給UI主執行緒.

使用的優點:

簡單,快捷

過程可控

使用的缺點:

在使用多個非同步操作和並需要進行Ui變更時,就變得複雜起來

Handler非同步實現的原理和適用的優缺點

在Handler 非同步實現時,涉及到 Handler, Looper, Message,Thread四個物件,實現非同步的流程是主執行緒啟動Thread(子執行緒)àthread(子執行緒)執行並生成Message-àLooper獲取Message並傳遞給HandleràHandler逐個獲取Looper中的Message,並進行UI變更。

使用的優點:

l結構清晰,功能定義明確

對於多個後臺任務時,簡單,清晰

使用的缺點:

在單個後臺非同步處理時,顯得程式碼過多,結構過於複雜(相對性)

AsyncTask實現單個進度條

首先我們得要一個佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.asus.mytest2.ProgressActivity">
<SeekBar android:layout_width="match_parent" android:layout_height="50dp" android:id="@+id/sk"
android:max="100"/>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="開始下載1" android:id="@+id/btn1_progress"/> </LinearLayout>

詳細的步驟我寫在程式碼中了:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();

    start.setOnClickListener(this);
    end.setOnClickListener(this);
}

/**
 * Params 啟動任務執行的輸入引數,比如HTTP請求的URL。它是可變型引數。 Progress 後臺任務執行的百分比 Result
 * 後臺執行任務最終返回的結果,比如String。 如果某個泛型引數不需要指定型別時,可將它的設定為了Void
 * 
 * @author TED
 *
 */
class MyTask extends AsyncTask<String, Integer, String> {

    /**
     * 該方法將在執行實際的後臺操作前被UI 執行緒呼叫。
     * 可以在該方法中做一些準備工作,如在介面上顯示一個進度條,或者一些控制元件的例項化,這個方法可以中實現。
     */
    @Override
    protected void onPreExecute() {
        tv.setText("下載中。。。");
        super.onPreExecute();
    }

    /**
     * 該方法執行在後臺執行緒中。這裡將主要負責執行那些很耗時的後臺處理工作 可以呼叫 publishProgress方法來更新實時的任務進度
     */
    @Override
    protected String doInBackground(String... params) {
        for(int i = 0; i<100; i++){
            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            publishProgress(i);
        }
        return null;
    }

    /**
     * 在doInBackground 執行完成後,onPostExecute 方法將被UI 執行緒呼叫,後臺的計算結果將通過該方法傳遞到UI
     * 執行緒, 並且在介面上展示給使用者.
     * 
     */
    @Override
    protected void onPostExecute(String result) {
        tv.setText("下載完成");
        super.onPostExecute(result);
    }

    /**
     * 在publishProgress方法被呼叫後,UI 執行緒將呼叫這個方法從而在介面上展示任務的進展情況,例如通過一個進度條進行展示。
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        progressBar.setProgress(values[0]);
        tv.setText("下載中"+values[0]+"%");
        super.onProgressUpdate(values);
    }


    /**
     * 在使用者取消執行緒操作的時候呼叫。在主執行緒中呼叫onCancelled()的時候呼叫。
     */
    @Override
    protected void onCancelled() {
        tv.setText("下載失敗");
        super.onCancelled();
    }

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.start:

        myTask.execute("下載中");
        break;
    case R.id.end:
        myTask.cancel(true);
        break;
    default:
        break;
    }

}

AsyncTask實現進度條主要還是在於要理解每一個方法需要幹什麼,那麼AsyncTask是否能實現兩根進度條互相不干擾的進行讀條呢,答案當然是肯定的

AsyncTask實現兩個進度條

先來一個佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.asus.mytest2.ProgressActivity">

    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/sk"
        android:max="100"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開始下載1"
        android:id="@+id/btn1_progress"/>

    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/sk2"
        android:max="100"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開始下載2"
        android:id="@+id/btn2_progress"/>

</LinearLayout>

在這裡,要實現多個執行緒,就要好好考慮方法體中可變長度的引數,居然是可變長度,那麼自然可以傳入多個引數,因此就能實現同時進行其它執行緒的操作

package com.example.asus.mytest2;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

public class ProgressActivity extends AppCompatActivity {

    private SeekBar progressBar1,progressBar2;
    private Button btn1, btn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress);

        progressBar1 = (SeekBar) findViewById(R.id.sk);
        progressBar2 = (SeekBar) findViewById(R.id.sk2);
        btn1 = (Button) findViewById(R.id.btn1_progress);
        btn2 = (Button) findViewById(R.id.btn2_progress);

        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btn1.setText("下載中。。。");
                btn1.setEnabled(false);
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,1);
            }
        });

        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                btn2.setText("下載中。。。");
                btn2.setEnabled(false);
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,2);
            }
        });

    }

    class MyTask extends AsyncTask<Integer, Integer, Integer> {


        @Override
        protected Integer doInBackground(Integer... values) {
            for (int i = 0; i <= 100; i+=5) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                publishProgress(i,values[0]);
            }
            return values[0];
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            switch (values[1]){
                case 1:
                    progressBar1.setProgress(values[0]);
                    btn1.setText("下載中" + values[0] + "%");
                    break;
                case 2:
                    progressBar2.setProgress(values[0]);
                    btn2.setText("下載中" + values[0] + "%");
                    break;
                default:
                    break;
            }
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Integer result) {
            switch (result){
                case 1:
                    btn1.setText("下載完成");
                    btn1.setEnabled(true);
                    break;
                case 2:
                    btn2.setText("下載完成");
                    btn2.setEnabled(true);
                    break;
                default:
                    break;
            }
            super.onPostExecute(result);
        }
    }
}

這裡我們在publishProgress(i,values[0]);傳入了兩個引數,通過onProgressUpdate方法來判斷需要進行的操作,在這裡,如要要讓程式知道那個是控制那個,我們則需要引入executeOnExecutor()方法,通過內部類來呼叫,這樣就可以完成實現多個執行緒的實現且互不干擾

相關推薦

使用AsyncTask完成進度載入

AsyncTask AsyncTask和Handler對比 AsyncTask實現的原理,和適用的優缺點 AsyncTask,是android提供的輕量級的非同步類,可以直接繼承AsyncTask,在類中實現非同步操作,並提供介面反饋當前非同步執行的程

Android學習---使用非同步內部類實現進度載入效果

Android學習—使用非同步內部類 為什麼要用AsyncTask? 答:我們可以用上述兩種方法來完成我們的非同步操作,加入要我們寫的非同步操作比較多,或者較為繁瑣, 難道我們new Thread()然後用上述方法通知UI更新麼?程式設計師都是比較喜歡偷懶的,既然官方給我 們

超炫的進度載入效果

  紅灰色調進度條                              

React + css3 實現circle圓環進度載入

【需求效果圖:如上圖所示】 需求:動態獲取不同的分數,圓環展示對應的百分比分數值: 正確率 70%以下提示文案:還需要繼續加油哦~ 正確率 70% - 90%以下提示文案:不錯,再加把勁~ 正確率 90%及以上提示文案:真棒! 資料描述:不同的測試

ProgressBar + AsyncTask (普通的進度)10秒後完成

xml 佈局簡單就不給出了 下面是 java 程式碼 package com.xiaoxiong.summer; import android.R; import android.app.Activity; import android.os.AsyncTask; i

如何建立一個*毫無用處*的進度顯示載入進度- 皮這一下很開心

看了下風雲小Q的空間分享, 覺得很有意思 皮這一下很開心 真開心 #include<iostream> #include<cstdlib> #include<windows.h> using namespace std; /*一個毫無用處的程式*/

Linux下實現進度程式. 通過makefile進行編譯. 建議自主完成一個彩色的進度.

Linux下用C語言完成一個彩色進度條 1.建一個Makefile檔案 2.vim Makefile test:test.c

CSS3實現頁面載入進度

什麼情況下會使用到頁面載入進度條? 當頁面中的需要載入的內容很多,使用者直接進入則看不到任何內容,體驗不好,這個時候就需要使用到頁面載入的一個動畫,在頁面載入結束後再 顯示主體內容。 實現頁面載入進度條有哪幾種方式? 一般可分為兩種, 1.設定多少時間後顯示頁面, 2.根據頁面載入的文件狀態來實現

淺談前端實現頁面載入進度以及 nprogress.js 的實現

以前在 Vue 的專案用了 nprogress 這個外掛,一直對於其如何得知載入進度充滿好奇,最近又看到了「前端如何實現頁面載入進度條」這個問題,今天週六恰好一探究竟。以下僅為一家之言,如有異議,歡迎指出。 前端的頁面載入進度條有兩種 首先不得不說,前端的頁面載入進度條其實有兩種,所以你得先搞清楚說的是哪

非同步載入遊戲場景與非同步載入遊戲資源進度

在Hierarchy檢視中我們可以看到該場景中“天生”的所有遊戲物件。天生的意思就是執行程式前該場景中就已經存在的所有遊戲物件。然後這些物件就會在執行完Application.LoadLevel(“yourScene”);方法後加載至記憶體當中。如果該場景中的遊戲物件過多那麼瞬間將會出現卡一下的情況

頁面載入進度實現——readyState和onreadystatechange

document.readyState 屬性返回當前文件的狀態(載入中……)。 共有四種取值: 1,uninitialized - 還未開始載入  uninitialized  英 [ʌnɪ'nɪʃlaɪzd]  未初始化 2,loading

白鷺egret專案資源的loading,介面的顯示與載入進度:ProgressBar;

1.用egret建立一個空的euigame專案; 2.點選f5執行空的專案[他自帶了一個載入的txt顯示]; EE:資源太少,載入速度太快,童鞋們可能注意不到; 然後,我們在egretwing的資源路徑加如下倆資料夾; loading【放載入介面用的圖片】和Pic【放測試loa

Unity3D之UGUI——製作非同步載入場景進度

      製作遊戲經常要實現兩個場景的切換,但由於載入場景需要一定時間,所以為了優化玩家體驗,在第一個場景中製作一個進度條顯示載入進度。     現在就在unity中實現,go go!開啟unity,新建場景 GameMai

自定義View載入進度首頁面

1.主頁面佈局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:

載入+監聽圖片資源載入製作進度

這兩天遇到一個新需求:一個一鏡到底的h5動畫。因為功能的特殊性,就要求我們提前監聽頁面的靜態圖片是否全部載入完畢。即處理預載入。 總結下來,下次這種需求需要提前注意以下幾點: 一、圖片而不是背景圖 本來,我所用到的圖都是用背景圖製作的(因為非介面返回的圖片都要求用背景圖)。 但是監聽靜態圖片時,後

Android進度、自動提示框、下拉框動態資料載入

1.進度條實現 佈局檔案: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

【Android】一、Progress進度實現的三種方式:主執行緒實現,Service載入,動態建立

前言 更新版本,上傳資料到服務端,都是需要進度顯示的,Android進度顯示兩種方式 ProgressDialog 和 ProgressBar 新版本中ProgressDialog不被推薦使用,所以專案採用ProgressBar 分為三種實現方式: 1、MainAct

Unity3D 場景切換載入進度實現

需要三個場景,場景A,場景B,場景C; 場景A:一個按鈕,點選載入場景B; 場景B:從A切換到C過度場景,載入進度條; 場景C:目標場景; 建立OnProgress.cs指令碼: using System.Collections; using System.Collections.Generic; usin

Android與js互動,帶進度載入H5頁面

private void initWebView() { WebSettings settings = wvResumeDetail.getSettings(); //支援JavaScript指令碼語言 settings

騰訊X5WebView+JsBridge互動及WebView載入進度效果實現

最近在專案開發中有不少頁面需要採用html的方式實現,自然而然就涉及到原生和js的互動問題,WebView也提供了addJavascriptInterface方法可以進行js的互動,實現也比較簡單,由於需要互動的地方比較多,還是沒有采用這種方式,使用了JsBridge第三方來實現,JsBridg