Message Handler报Java.lang.NullPointerException

最近在做手机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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值