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("http://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("http://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(); } }}