Message Handler报Java.lang.NullPointerException

来源:互联网 发布:插画网络课程 编辑:程序博客网 时间:2024/04/30 08:17

最近在做手机APP向PCServer端发送数据的小项目,Android 程序中为方便线程间通信(主要是高版本API不允许主线程内执行耗时服务,包括网络通信等),使用Message,Handler。

起初想法:

UI线程:利用Message封装并发送,同时接收子线程传来的数据;

子线程:利用handler进行处理消息handleMessage,同时得到Server端传回数据,并发送到主线程。

1、Server端已运行;

2、Android程序含有Internet权限,输入ServerIP地址正确,端口和Server端设置端口一致

3、添加了输入为空的异常捕捉

运行程序后,总是在message和handler的handler.sendMessage(msg)报Java.lang.NullPointerException。

探索:

1、找到了之前写得message和handler成功代码

发现自己在发送信息时只有一句话

//param 0x01---int//param string-object 这里使用的字符串handler.obtainMessage(0x01,string).sendToTarget();
然后就修改为上述句子,运行还是出错;

2、难道是封装的信息为空?

Message msg=new Message();msg.what=0x02;msg.obj="hello world!";System.out.println(msg.obj.toString());handler.sendMessage(msg);
结果可以输出封装信息(msg.obj),还是在handler.sendMessage(msg)报NullPointerException

3、是不是msg为空?

分析上述2中代码,新建Message对象没有报错,按理说不是空指针,但我还是不确定,判断一下。

Message msg=new Message();msg.what=0x03;msg.obj="Hello world!";if(msg!=null){     System.out.println("msg is not null!");handler.sendMessage(msg);}
输出“msg is not null!",handler.sendMessage(msg)报空指针异常,这样确定了是handler为空。

4、子线程中处理UI线程信息的handler是传递过来的,Handler的发起和处理都因该对应起来。

子线程:

public class TestThread implements Runnable{     Handler mhandler;     //Constructor     public TestThread(Handler handler){    //将UI的handler传递过来,并用于sendMessage     this.mhandler=handler;     }     @Override     public void run(){               Message msg=new Message();               msg.what=0x02;               msg.obj="hello server!";               mhandler.sendMessage(msg);     }}
主线程:

public class TestHandler extends Activity{     ……     Button bt;     Handler uihandler;     ……     public void onCreate(***){           ……           bt=(Button)findViewById();           bt.setOnClickListener(new mOnClickListener());           ……      }      public class mOnClickListener implements OnClickListener{      ……      //new thread      new Thread(new TestThread(uihandler)).start();      //handleMessage       uihandler=new Handler(){             ……       };              ……     }}


我的主线程和子线程大致是这样,仔细查看代码才发现:主线程中Handler在新建Thread之前并没有初始化,而是在线程发起后new Handler对象,所以报NullPointerException,将位置对换,实现主线程与子线程的通信。

正确的主线程结构是:

public class TestHandler extends Activity{     ……     Button bt;     Handler uihandler;     ……     public void onCreate(***){           ……           bt=(Button)findViewById();           bt.setOnClickListener(new mOnClickListener());           ……      }      public class mOnClickListener implements OnClickListener{      ……           //handleMessage       uihandler=new Handler(){             ……       };        //new thread      new Thread(new TestThread(uihandler)).start();       ……     }}

5、主线程向子线程发送封装消息时,应当调用子线程的Handler发送消息。

//currentHandler是在子线程中声明的handler对象,用于接收主线程发送的消息TestThread.currentHandler.sendMessage(msg);

public class TestThread implements Runnable{       ……       Handler mhandler;//       Handler currentHandler;//接收主线程信息       ……       currentHandler=new Handler(){              public void handleMessage(){                    ……              }        }}




0 1