刚刚上手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组件。

更多相关文章

  1. 如何添加Android返回键的退出功能
  2. android中The connection to adb is down,问题和解决
  3. Android屏幕元素层次结构
  4. Android控件-多选按钮、单选按钮
  5. Android(安卓)Studio——Android(安卓)Studio更新升级方法
  6. Android-Jni线程(二)— 线程锁之生产者消费者
  7. Android——属性动画(Property Animation)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. 立即执行函数 箭头函数等
  2. 210330 CSS grid布局仿写
  3. 附解决方案,小程序获取的用户信息中昵称图
  4. 工具之_文本处理工具
  5. 【JS基础入门】JavaScript基础之值与引用
  6. ensp起不来的原因汇总(长期更新)
  7. 为什么对象存储一定要成为2018年数据战略
  8. 简化数据获取!Uber开源深度学习分布训练库
  9. LinkedIn开源TonY:在Hadoop上运行TensorFl
  10. Kafka落选!InfoWorld最佳开源数据平台奖公