android 訪問網絡不能在主線程中進行以及在線程中操作UI的解決方法

剛剛上手android,在寫一個利用Socket與服務器端進行通信的Demo時候報了一個android.os.NetworkOnMainThreadException的異常:

服務器端:

public class SimpleServer {

public static void main(String[] args){

try {

ServerSocket ss=new ServerSocket(40000);

System.out.println("等待連接......");

while(true){

Socket s=ss.accept();

OutputStream os=s.getOutputStream();

os.write("hello".getBytes("utf-8"));

os.close();

s.close();

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

求助度娘後發現是SDK的版本問題,android4.0中訪問網絡不能在主程序中進行,行吧,那就老老實實的重新開啓一個線程:

new Thread(){

public void run(){

try {

Socket s=new Socket("172.22.16.26", 40000);

BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));

String line=br.readLine();

show.setText("服務器說:"+line);

br.close();

s.close();

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}.start();

結果又報了異常:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

相信各位已經看出了在下犯了一個很低級的錯誤:在新啓的線程中操作UI,UI線程是非線程安全的,Android平臺不允許Activity新啓動的線程訪問該Activity裏的界面組件,這時就要藉助Handler的消息傳遞機制了:

new Thread(){

public void run(){

try {

Socket s=new Socket("172.18.6.26",40000);

BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));

String line=br.readLine();

//System.out.println("服務器說:"+line);

Message msg=new Message();

msg.what=0x123;

msg.obj=line;

myhandler.sendMessage(msg);

br.close();

s.close();

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}.start();

然後重寫handlerMessage方法獲取消息:

final Handler myhandler=new Handler(){

public void handleMessage(Message msg){

if(msg.what==0x123){

System.out.println("--------------->"+msg.obj);

show2.setText((String)msg.obj);

}

}

};

當新線程發送消息時,該方法自動被調用,handlerMessage(Message msg)方法依舊位於主線程中,所以可以動態的修改UI組件。

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