Android UDP通信之Handler、Activity、UI更新
2011-12-15 15:43
351 查看
碰到了一些问题,列出几个说说
1.ERROR/JavaBinder(1726): android.util.AndroidRuntimeException: { what=102 when=330076886 obj=android.os.BinderProxy@325fb830 } This message is already in use.
2.ERROR/global(29212): java.lang.UnsupportedOperationException
ERROR/global(29212): at java.lang.VMThread.suspend(VMThread.java:61)
ERROR/global(29212): at java.lang.Thread.suspend(Thread.java:1403)
3.ERROR/DEBUG_TAG(31012): java.net.SocketException: Interrupted system call
可能文章题目有些不合适,但不管了,先贴代码,其中用到的Activity生命周期、Handler使用参看参考文章
UDPSender:向指定IP发送消息“Hello+i(动态自增值)”,
UDPRecever:接收UDP消息,并在一个TextView中显示
layout中的main.xml
对问题1,需要注意每次的消息需要updateBarHandler.obtainMessage()获取一下,在Activity一直在可见状态(运行)时,如果没有这句,上面的程序不会有问题,但是当使用回退或者锁屏后恢复,会发现问题1(还有个前提是要有收到UDP消息)。具体原因还是不清,因为程序在回退键后重新进入时是重新执行了线程的run的,猜测是不是重新分配时仍沿用了老的对象空间(原来的server也是在线程里,也会抛出地址被使用的异常)。
对问题2,是在onPause()和onResume()时,想把线程挂起和唤醒,但每次好像不按照自己想的来,还抛出异常,可能是内部不支持?该方法帮助提示是deprecated的了。
对问题3,每次按返回键,主菜单,电源键(锁屏)了,返回后都会抛出,看上面的代码,能知道是线程里跳出while循环了,相当于是线程死了,至于什么原因导致while中的socket抛出异常,还是不知道,猜测是socket阻塞获取消息被系统打断,抛出异常。
问题原因还是不清晰,希望有解决的告知(通常没有人会告知,懂的人看不到这文章,看到的又不会,O(∩_∩)O~ %>_<% )。
转载注明出处:/article/2707871.html
邮箱:w.7849516230@163.com
参看文章:
1.Activity生命周期 http://www.2cto.com/kf/201110/108421.html
2.Handler的使用 http://www.eoeandroid.com/thread-72298-1-1.html
3.android的Handler http://www.cnblogs.com/keyindex/articles/1822463.html
1.ERROR/JavaBinder(1726): android.util.AndroidRuntimeException: { what=102 when=330076886 obj=android.os.BinderProxy@325fb830 } This message is already in use.
2.ERROR/global(29212): java.lang.UnsupportedOperationException
ERROR/global(29212): at java.lang.VMThread.suspend(VMThread.java:61)
ERROR/global(29212): at java.lang.Thread.suspend(Thread.java:1403)
3.ERROR/DEBUG_TAG(31012): java.net.SocketException: Interrupted system call
可能文章题目有些不合适,但不管了,先贴代码,其中用到的Activity生命周期、Handler使用参看参考文章
UDPSender:向指定IP发送消息“Hello+i(动态自增值)”,
package com.udp.androidStudy.lx; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class udpSender { public static void main(String[] args) { try { //定义要发送的字符串并转为byte数组 byte[] buffer = "Hello".getBytes(); int messageCount=0; //目标ip地址 InetAddress wiFiDestIP = InetAddress.getByName("192.168.43.1"); //定义UDP数据包,需要指定目标地址及端口号 DatagramPacket packet = new DatagramPacket(buffer,buffer.length,wiFiDestIP,54321); //发送数据 DatagramSocket sendSocket = new DatagramSocket(); StringBuffer dataString =new StringBuffer(); while(true){ sendSocket.send(packet); System.out.println("Send Data:" + new String(packet.getData())); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } messageCount++; buffer = ("Hello" + messageCount).getBytes(); packet.setData(buffer,0,buffer.length); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
UDPRecever:接收UDP消息,并在一个TextView中显示
package com.udp.androidStuy.lx; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.TextView; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.SocketOptions; import java.net.UnknownHostException; public class UDPRecever extends Activity { /** Called when the activity is first created. */ TextView mainTextView; Thread mReceiveThread; DatagramSocket server; int mMessageCountInt = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mainTextView = (TextView) findViewById(R.id.mainTextView); // 定义UDP监听 try { server = new DatagramSocket(54321); //server.setReuseAddress(true); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.e("myLog","activity run"); mReceiveThread= new Thread(updateThread); mReceiveThread.start(); mainTextView.append("开始接收数据:\n"); } @Override protected void onResume() { super.onResume(); if(!mReceiveThread.isAlive()){ if(server.isClosed()){ Log.e("myLog","Resume thread"); // 定义UDP监听 try { server = new DatagramSocket(54321); //server.setReuseAddress(true); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } } mReceiveThread= new Thread(updateThread); mReceiveThread.start(); //mReceiveThread.run(); } /*if(!mReceiveThread.isAlive()){ mReceiveThread.resume(); }*/ } @Override protected void onPause() { super.onPause(); /*if(mReceiveThread.isAlive()){ mReceiveThread.suspend(); }*/ server.close(); } // 使用匿名内部类来复写Handler当中的handlerMessage()方法 final Handler updateBarHandler = new Handler() { @Override public void handleMessage(Message msg) { Log.e("myLog","handleMessage"); //每次只保存显示30个 if(mMessageCountInt++ >= 30){ //mainTextView.computeScroll(); //mainTextView.scrollBy(0, mMessageCountInt + 10); mainTextView.setText(""); mMessageCountInt = 0; } mainTextView.append((msg.getData()).getString("data")); } }; // 线程类,该类使用匿名内部类的方式进行声明 Runnable updateThread = new Runnable() { public void run() { // TODO Auto-generated method stub Log.e("myLog","执行run"); // 得到一个消息对象,Message类是android系统提供的 Message msg = new Message(); Bundle b = new Bundle(); try { // 定义缓冲区 byte[] buffer = new byte[1024]; // 定义接收数据包 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); while (true) { msg = updateBarHandler.obtainMessage(); // 接收数据 server.receive(packet); // 判断是否收到数据,然后输出字符串 if (packet.getLength() > 0) { String str = new String(buffer, 0, packet .getLength()); b.putString("data", str + "\n"); msg.setData(b); // 将Message对象加入到消息队列当中 updateBarHandler.sendMessage(msg); Log.e("myLog", "sendMessage"); } } } catch (SocketException e) { Log.e("DEBUG_TAG", e.toString());// e.printStackTrace();原来还想外围加个while用label跳转,试试而已 } catch (IOException e) { Log.e("DEBUG_TAG", e.toString());// e.printStackTrace(); } // Log.e("myLog","Exception"); } }; }很多注释还留着,可以看看试了哪些东西。
layout中的main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/mainTextView" android:layout_width="fill_parent" android:layout_height="fill_parent" > </TextView> </ScrollView> </LinearLayout>首先说说Activity,其生命周期不知多少人说了又说,我这里只说这个程序的情况,在按下返回键时,相当于退出程序,重新进入时,执行Activity的onCreate();按下电源键锁屏时,重新进入Activity,没有执行onCreate(),但是由于有些原因另启的线程死了,抛出异常(问题3)的情况,线程死原因在后面,算是执行完毕了。
对问题1,需要注意每次的消息需要updateBarHandler.obtainMessage()获取一下,在Activity一直在可见状态(运行)时,如果没有这句,上面的程序不会有问题,但是当使用回退或者锁屏后恢复,会发现问题1(还有个前提是要有收到UDP消息)。具体原因还是不清,因为程序在回退键后重新进入时是重新执行了线程的run的,猜测是不是重新分配时仍沿用了老的对象空间(原来的server也是在线程里,也会抛出地址被使用的异常)。
对问题2,是在onPause()和onResume()时,想把线程挂起和唤醒,但每次好像不按照自己想的来,还抛出异常,可能是内部不支持?该方法帮助提示是deprecated的了。
对问题3,每次按返回键,主菜单,电源键(锁屏)了,返回后都会抛出,看上面的代码,能知道是线程里跳出while循环了,相当于是线程死了,至于什么原因导致while中的socket抛出异常,还是不知道,猜测是socket阻塞获取消息被系统打断,抛出异常。
问题原因还是不清晰,希望有解决的告知(通常没有人会告知,懂的人看不到这文章,看到的又不会,O(∩_∩)O~ %>_<% )。
转载注明出处:/article/2707871.html
邮箱:w.7849516230@163.com
参看文章:
1.Activity生命周期 http://www.2cto.com/kf/201110/108421.html
2.Handler的使用 http://www.eoeandroid.com/thread-72298-1-1.html
3.android的Handler http://www.cnblogs.com/keyindex/articles/1822463.html
相关文章推荐
- 利用Handler更简单的实现Service与Activity的通信,更新UI
- android之在activity中控制另一个activity的UI更新_如何在activity之间传递handler
- 《Handler: Activity 之间通过 Handler 通信》 & 《通过Handler更新UI》
- android之在activity中控制另一个activity的UI更新_如何在activity之间传递handler&利用broadcast广播机制
- android之在activity中控制另一个activity的UI更新_如何在activity之间传递handler
- 利用Handler更简单的实现Service与Activity的通信,更新UI
- android之在activity中控制另一个activity的UI更新_如何在activity之间传递handler
- 利用Handler来更新android的UI
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android 更新UI的两种方法——handler和runOnUiThread()
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android 异步更新UI----handler+thread
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android 更新UI的两种方法——handler和runOnUiThread()
- Android 更新UI的两种方法——handler和runOnUiThread()
- Android 异步更新UI-线程池-Future-Handler实例分析
- 利用Handler来更新android的UI
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制