android HTTP 通信, XML 解析, 通過 Hander 實現異步消息處理(2)

android HTTP 通信, XML 解析, 通過 Hander 實現異步消息處理(2)
2010-02-03 10:56
2、用 Handler 來實現異步消息處理,以一個可以實時彙報下載進度的異步下載類爲例
開發一個 Android 類庫,本例中此類庫名爲 webabcd_util

New -> Java Project
項目上點右鍵 -> Build Path -> Add Libraries -> User Library -> User Libraries -> New -> 爲類庫起個名字 -> 選中這個類庫 -> Add JARs 導入 Android 的 jar 包
項目上點右鍵 -> Build Path -> Add Libraries -> User Library -> 選擇 Android 庫

DownloadManagerAsync.java

代碼
package webabcd.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.protocol.HTTP;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

// 以一個實例,即異步下載,來演示 Android 的異步消息處理(用 Handler 的方式)
public class DownloadManagerAsync {

    public DownloadManagerAsync() {

    }

    // 實例化自定義的 Handler
    EventHandler mHandler = new EventHandler(this);

    // 按指定 url 地址下載文件到指定路徑
    public void download(final String url, final String savePath) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    sendMessage(FILE_DOWNLOAD_CONNECT);
                    URL sourceUrl = new URL(url);
                    URLConnection conn = sourceUrl.openConnection();
                    InputStream inputStream = conn.getInputStream();

                    int fileSize = conn.getContentLength();

                    File savefile = new File(savePath);
                    if (savefile.exists()) {
                        savefile.delete();
                    }
                    savefile.createNewFile();

                    FileOutputStream outputStream = new FileOutputStream(
                            savePath, true);

                    byte[] buffer = new byte[1024];
                    int readCount = 0;
                    int readNum = 0;
                    int prevPercent = 0;
                    while (readCount < fileSize && readNum != -1) {
                        readNum = inputStream.read(buffer);
                        if (readNum > -1) {
                            outputStream.write(buffer);
                            readCount = readCount + readNum;

                            int percent = (int) (readCount * 100 / fileSize);
                            if (percent > prevPercent) {
                                // 發送下載進度信息
                                sendMessage(FILE_DOWNLOAD_UPDATE, percent,
                                        readCount);

                                prevPercent = percent;
                            }
                        }
                    }

                    outputStream.close();
                    sendMessage(FILE_DOWNLOAD_COMPLETE, savePath);

                } catch (Exception e) {
                    sendMessage(FILE_DOWNLOAD_ERROR, e);
                    Log.e("MyError", e.toString());
                }
            }
        }).start();
    }

    // 讀取指定 url 地址的響應內容
    public void download(final String url) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    sendMessage(FILE_DOWNLOAD_CONNECT);
                    URL sourceUrl = new URL(url);
                    URLConnection conn = sourceUrl.openConnection();
                    conn.setConnectTimeout(3000);
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(conn.getInputStream(),
                                    HTTP.UTF_8));

                    String line = null;
                    StringBuffer content = new StringBuffer();
                    while ((line = reader.readLine()) != null) {
                        content.append(line);
                    }

                    reader.close();

                    sendMessage(FILE_DOWNLOAD_COMPLETE, content.toString());

                } catch (Exception e) {
                    sendMessage(FILE_DOWNLOAD_ERROR, e);
                    Log.e("MyError", e.toString());
                }
            }
        }).start();
    }

    // 向 Handler 發送消息
    private void sendMessage(int what, Object obj) {
        // 構造需要向 Handler 發送的消息
        Message msg = mHandler.obtainMessage(what, obj);
        // 發送消息
        mHandler.sendMessage(msg);
    }

    private void sendMessage(int what) {
        Message msg = mHandler.obtainMessage(what);
        mHandler.sendMessage(msg);
    }

    private void sendMessage(int what, int arg1, int arg2) {
        Message msg = mHandler.obtainMessage(what, arg1, arg2);
        mHandler.sendMessage(msg);
    }

    private static final int FILE_DOWNLOAD_CONNECT = 0;
    private static final int FILE_DOWNLOAD_UPDATE = 1;
    private static final int FILE_DOWNLOAD_COMPLETE = 2;
    private static final int FILE_DOWNLOAD_ERROR = -1;

    // 自定義的 Handler
    private class EventHandler extends Handler {
        private DownloadManagerAsync mManager;

        public EventHandler(DownloadManagerAsync manager) {
            mManager = manager;
        }

        // 處理接收到的消息
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case FILE_DOWNLOAD_CONNECT:
                if (mOnDownloadConnectListener != null)
                    mOnDownloadConnectListener.onDownloadConnect(mManager);
                break;
            case FILE_DOWNLOAD_UPDATE:
                if (mOnDownloadUpdateListener != null)
                    mOnDownloadUpdateListener.onDownloadUpdate(mManager,
                            msg.arg1);
                break;
            case FILE_DOWNLOAD_COMPLETE:
                if (mOnDownloadCompleteListener != null)
                    mOnDownloadCompleteListener.onDownloadComplete(mManager,
                            msg.obj);
                break;
            case FILE_DOWNLOAD_ERROR:
                if (mOnDownloadErrorListener != null)
                    mOnDownloadErrorListener.onDownloadError(mManager,
                            (Exception) msg.obj);
                break;
            default:
                break;
            }
        }
    }

    // 定義連接事件
    private OnDownloadConnectListener mOnDownloadConnectListener;
    public interface OnDownloadConnectListener {
        void onDownloadConnect(DownloadManagerAsync manager);
    }
    public void setOnDownloadConnectListener(OnDownloadConnectListener listener) {
        mOnDownloadConnectListener = listener;
    }

    // 定義下載進度更新事件
    private OnDownloadUpdateListener mOnDownloadUpdateListener;
    public interface OnDownloadUpdateListener {
        void onDownloadUpdate(DownloadManagerAsync manager, int percent);
    }
    public void setOnDownloadUpdateListener(OnDownloadUpdateListener listener) {
        mOnDownloadUpdateListener = listener;
    }

    // 定義下載完成事件
    private OnDownloadCompleteListener mOnDownloadCompleteListener;
    public interface OnDownloadCompleteListener {
        void onDownloadComplete(DownloadManagerAsync manager, Object result);
    }
    public void setOnDownloadCompleteListener(
            OnDownloadCompleteListener listener) {
        mOnDownloadCompleteListener = listener;
    }

    // 定義下載異常事件
    private OnDownloadErrorListener mOnDownloadErrorListener;
    public interface OnDownloadErrorListener {
        void onDownloadError(DownloadManagerAsync manager, Exception e);
    }
    public void setOnDownloadErrorListener(OnDownloadErrorListener listener) {
        mOnDownloadErrorListener = listener;
    }
}


調用上面的自定義的 Android 類庫

項目上點右鍵 -> Properties -> Java Build Path -> Projects -> Add 引用上面的類庫

Main.java

代碼
package com.webabcd.handler;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

import webabcd.util.DownloadManagerAsync;

public class Main extends Activity implements
        DownloadManagerAsync.OnDownloadCompleteListener,
        DownloadManagerAsync.OnDownloadUpdateListener,
        DownloadManagerAsync.OnDownloadErrorListener {
   
    TextView txt;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        DownloadManagerAsync manager = new DownloadManagerAsync();
        manager.setOnDownloadCompleteListener(this);
        manager.setOnDownloadUpdateListener(this);
        manager.download("http://files.cnblogs.com/webabcd/Android.rar", "/sdcard/Android.rar");
       
        txt = (TextView) this.findViewById(R.id.txt);
        txt.setText("開始下載");
    }

    public void onDownloadComplete(DownloadManagerAsync manager, Object result) {

        txt.setText("下載完成");
    }
   
    public void onDownloadUpdate(DownloadManagerAsync manager, int percent) {

        txt.setText("下載進度:" + String.valueOf(percent) + "%");
    }
   
    public void onDownloadError(DownloadManagerAsync manager, Exception e) {

        txt.setText("下載出錯");
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章