Android之Handler在新線程中讀取網絡的兩種方法

方法一:

創建一個Thread,然後調用start方法。

實例:

package com.example.android_handle;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.util.ByteArrayBuffer;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private Button start;
    private TextView text;

    Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            text.append(msg.obj + "\n");
        }

    };

    Runnable newTread = new Runnable() {
        String content;

        @Override
        public void run() {
            // TODO Auto-generated method stub
            // 網絡處理
            // 首先獲得一個消息結
            Message msg = handler.obtainMessage();
            // 給消息結構的arg1參數賦值
            try {
                URL uri = new URL("https://112.74.78.53/scut-lib/"
                        + "library/hotReading.php");
                URLConnection ucon = uri.openConnection();
                ucon.setConnectTimeout(10000);
                InputStream is = ucon.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                ByteArrayBuffer baf = new ByteArrayBuffer(100);
                int current = 0;
                while ((current = bis.read()) != -1) {
                    baf.append((byte) current);
                }
                content = new String(baf.toByteArray(), "UTF-8");
            } catch (Exception e) {
                content = "error";
            }
            msg.obj = content;
            handler.sendMessage(msg);
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = (Button) findViewById(R.id.start);
        text = (TextView) findViewById(R.id.text);

        start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Thread t = new Thread(newTread);
                t.start();
            }

        });
    }

}

方法二:

利用android開發框架中的looper類來實現

Looper是用於給一個線程添加一個消息隊列(MessageQueue),並且循環等待,當有消息時會喚起線程來處理消息的一個工具,直到線程結束為止。通常情況下不會用到Looper,因為對於Activity,Service等系統組件,Frameworks已經為我們初始化好瞭線程(俗稱的UI線程或主線程),在其內含有一個Looper,和由Looper創建的消息隊列,所以主線程會一直運行,處理用戶事件,直到某些事件(BACK)退出。

如果,我們需要新建一個線程,並且這個線程要能夠循環處理其他線程發來的消息事件,或者需要長期與其他線程進行復雜的交互,這時就需要用到Looper來給線程建立消息隊列。

使用Looper也非常的簡單,它的方法比較少,最主要的有四個:
public static prepare();
public static myLooper();
public static loop();
public void quit();

使用方法如下:
1. 在每個線程的run()方法中的最開始調用Looper.prepare(),這是為線程初始化消息隊列。
2. 之後調用Looper.myLooper()獲取此Looper對象的引用。這不是必須的,但是如果你需要保存Looper對象的話,一定要在prepare()之後,否則調用在此對象上的方法不一定有效果,如looper.quit()就不會退出。
3. 在run()方法中添加Handler來處理消息
4. 添加Looper.loop()調用,這是讓線程的消息隊列開始運行,可以接收消息瞭。
5. 在想要退出消息循環時,調用Looper.quit()註意,這個方法是要在對象上面調用,很明顯,用對象的意思就是要退出具體哪個Looper。如果run()中無其他操作,線程也將終止運行。

實例:

package com.example.android_handle;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.util.ByteArrayBuffer;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private Button start;
    private TextView text;
    private Handler handler;
    private NewThread thread;
    private String s="";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = (Button) findViewById(R.id.start);
        text = (TextView) findViewById(R.id.text);
        text.setMovementMethod(ScrollingMovementMethod.getInstance()); 

        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                s = s + msg.obj + "\n";
                text.setText(s);
            }

        };

        start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                thread = new NewThread();
            }

        });
    }

    private class NewThread extends Thread {
        private Handler mHandler;
        private Looper mLooper;
        private String content;

        public NewThread() {
            start();
        }

        public void run() {
            Looper.prepare();
            mLooper = Looper.myLooper();
            mHandler = new Handler(mLooper) {

                @Override
                public void handleMessage(Message msg) {
                    // TODO Auto-generated method stub
                    Message newMsg = Message.obtain();
                    newMsg.obj = msg.obj;
                    handler.sendMessage(newMsg);
                }

            };
            try {
                URL uri = new URL("https://112.74.78.53/scut-lib/"
                        + "library/hotReading.php");
                URLConnection ucon = uri.openConnection();
                ucon.setConnectTimeout(10000);
                InputStream is = ucon.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                ByteArrayBuffer baf = new ByteArrayBuffer(100);
                int current = 0;
                while ((current = bis.read()) != -1) {
                    baf.append((byte) current);
                }
                content = new String(baf.toByteArray(), "UTF-8");
            } catch (Exception e) {
                content = e.toString();
            }
            Message msg = Message.obtain();
            msg.obj = content;
            mHandler.sendMessage(msg);
            Looper.loop();
        }

    }

}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。