主线程和网络线程之间用handler传递数据时,handler空指针错误。已经快疯掉了。。。。

u011177596 2014-08-29 09:11:26

子线程中有handleMessage方法,但是在主线程中用sendmessage传递数据时,报handler对象是空指针。就是图中的mNetHandler。

哪里的问题?
...全文
469 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingzhong128 2016-03-16
  • 打赏
  • 举报
回复
//开启网络线程 NetThread mNetThread = new NetThread(); mNetThread.start(); start()之后线程不是一定会立即执行,有可能直接执行完后面的语句才开始新线程,在这句后面加while (mNetHandler == null);
yezifeil 2016-03-16
  • 打赏
  • 举报
回复
楼主我也遇到相同问题,请问你解决了吗?
u011177596 2014-08-30
  • 打赏
  • 举报
回复
引用 9 楼 skgary 的回复:
[quote=引用 7 楼 u011177596 的回复:] [quote=引用 5 楼 YKDSea 的回复:] returnLocation()这个函数里面又定义了一个局部的mNetHandler? mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。
我在主线程和网络线程里都有handler,想这让实现来回通信。 我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决?[/quote] 你是纯为了学习呢?还是为了解决问题? [/quote] 解决问题
lionfresh 2014-08-30
  • 打赏
  • 举报
回复
handler运行的looper呢
海中水草 2014-08-30
  • 打赏
  • 举报
回复
这个问题解决的一个常用方法是:打log看程序运行的情况,就可以直接的看到线程运行了没,变量为什么为空·~~~~~~~~~从楼主的回复中反映出,出现问题后解决问题时都是靠推测,而不是看实际的运行数据。
skgary 2014-08-30
  • 打赏
  • 举报
回复
引用 7 楼 u011177596 的回复:
[quote=引用 5 楼 YKDSea 的回复:] returnLocation()这个函数里面又定义了一个局部的mNetHandler? mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。
我在主线程和网络线程里都有handler,想这让实现来回通信。 我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决?[/quote] 你是纯为了学习呢?还是为了解决问题?
  • 打赏
  • 举报
回复
LZ先去Baidu下HandlerThread吧
u011177596 2014-08-30
  • 打赏
  • 举报
回复
引用 5 楼 YKDSea 的回复:
returnLocation()这个函数里面又定义了一个局部的mNetHandler? mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。
我在主线程和网络线程里都有handler,想这让实现来回通信。 我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决?
skgary 2014-08-30
  • 打赏
  • 举报
回复
我建议 你子线程里只需要拿完,Post回主线程就可以了,主线程里收到相应的回复,把子线程的变量置空。 主线程要取东西,判断一下子线程对像引用 是不是用为空,如果为空,则说明没有子线程在运行,直接再start一个子线程就好了。
dali_yan 2014-08-30
  • 打赏
  • 举报
回复
代码太乱了,纯粹死为了实现功能而实现功能毫无设计可言,这样造成的结果就是自己都不知道执行顺序是怎样的。你应当分开,网络请求放在一个类或者一个方法里面,handler里面只是执行更新UI线程的操作,Thread里面请求网络操作和通知handler更新界面。你为什么要在子线程中使用handler,而在handler里面又请求网络,这样会造成很多未知的错误,就像你的为null错误,因为线程的生命周期你是很难控制的。所以你应当让每个线程独立开来,不要相互影响。
skgary 2014-08-30
  • 打赏
  • 举报
回复
如果为了解决问题还不简单啊。 子线程里就不要用handler了,run结束的时候,给主线程里的handler post消息即可。 如果你还要再取别的内容,就再new/start一个子线程出来。
sky-Z 2014-08-29
  • 打赏
  • 举报
回复
returnLocation()这个函数里面又定义了一个局部的mNetHandler? mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。
sagittarius1988 2014-08-29
  • 打赏
  • 举报
回复
你这里 mNetThread.start();后,下面的给子线程发消息可不是说会等你子线程执行完,mNetHandler初始化后才继续执行下面的步骤给子线程发消息的。 而且就算你把mNetHandler初始化放到线程外,你这个做法是有问题的,因为你网络请求方handler里执行,照样还是在UI线程里执行,这样可能会引起无响应
public String returnLocation() {
 
        // System.out.println("FallLocation          "+mlatitude);
         
        
        Handler mNetHandler = new Handler(){
 
                @Override
                public void handleMessage(Message msg) {
                    // TODO Auto-generated method stub
                    double latitude = (double) (msg.arg1) / 1000000f;
                    double longitude = (double) (msg.arg2) / 1000000f;
                     //开启网络线程
                     NetThread mNetThread = new NetThread(latitude,longitude);
                     mNetThread.start();
                     
                }
                 
            }; 
         
        mMainHandler = new Handler() {
 
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                // 接收网络线程的消息
                if(msg.what == ADDRESS){
                    address = (String) msg.obj;
                }
                 
            }
        };
         
         
        try {
            // 发送给子线程的消息
            mNetHandler.sendMessage(mNetHandler.obtainMessage(COORD,
                    (int) (mlatitude * 1000000),
                    (int) (mlongitude * 1000000)));   
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
         
        return address;
    }
 
    class NetThread extends Thread {
	
	double latitude ,longitude;
 
 public NetThread(double latitude,double longitude){
         this.latitude = latitude;
         this.longitude = longitude;
 }
        @Override
        public void run() {
            // TODO Auto-generated method stub
              
            System.out.println("handleMessage           " + latitude);
            System.out.println("handleMessage           " + longitude);
            // 耗时的操作
            String strResult = null;
            // 获取json数据
           try {
                  String httpUrl = "http://api.map.baidu.com/geocoder/v2/?ak=0KCws1IBokt9kvmoV0IT1gS3&callback=renderReverse&location="
                                    + latitude + "," + longitude + "&output=json&pois=0";
                  // HttpGet连接对象
                   HttpGet httpRequest = new HttpGet(httpUrl);
                   // 取得HttpClient对象
                   HttpClient httpclient = new DefaultHttpClient();
                   // 请求HttpClient,取得HttpResponse
                  HttpResponse httpResponse = httpclient.execute(httpRequest);
                  // 请求成功
                   if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                      // 取得返回的字符串
                        strResult = EntityUtils.toString(httpResponse.getEntity());
                   }
             } catch (Exception e) {
                     // TODO: handle exception
                      e.printStackTrace();
              }
 
             // 解析json
              try {
                      JSONTokener jsonParser = new JSONTokener(strResult);
                      JSONObject js = (JSONObject) jsonParser.nextValue();
                      JSONObject result = js.getJSONObject("result");
                      formatted_address = result.getString("formatted_address");
 
                  } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                  }
                         
              mMainHandler.sendMessage(mMainHandler.obtainMessage(ADDRESS,
                                formatted_address));
			
 
      }
 }
u011177596 2014-08-29
  • 打赏
  • 举报
回复
引用 2 楼 skgary 的回复:
你这个为null ,估计没有new过吧?
我在子线程里new的。 我把所有代码贴上来

package cn.edu.nuist.Test14081300;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class FallLocation {

	private String formatted_address;
	private double mlatitude, mlongitude;
	private int ADDRESS = 1;
	private int COORD = 2;
	private String address;

	private Handler mMainHandler, mNetHandler;

	public FallLocation(double lati, double longi) {
		// TODO Auto-generated constructor stub
		mlatitude = lati;
		mlongitude = longi;	
	}

	public String returnLocation() {

		// System.out.println("FallLocation          "+mlatitude);

		Handler mNetHandler = new Handler();
		
        //开启网络线程
		NetThread mNetThread = new NetThread();
		mNetThread.start();
		
		
		mMainHandler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				// 接收网络线程的消息
				if(msg.what == ADDRESS){
					address = (String) msg.obj;
				}
				
			}
		};
		
		
		try {
			// 发送给子线程的消息
			mNetHandler.sendMessage(mNetHandler.obtainMessage(COORD,
					(int) (mlatitude * 1000000),
					(int) (mlongitude * 1000000)));	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		return address;
	}

	class NetThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			
			
			Looper.prepare();

			mNetHandler = new Handler(){

				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);

					
						
						double latitude = (double) (msg.arg1) / 1000000f;
						double longitude = (double) (msg.arg2) / 1000000f;

						
						System.out.println("handleMessage           " + latitude);
						System.out.println("handleMessage           " + longitude);
						// 耗时的操作
						String strResult = null;
						// 获取json数据
						try {
							String httpUrl = "http://api.map.baidu.com/geocoder/v2/?ak=0KCws1IBokt9kvmoV0IT1gS3&callback=renderReverse&location="
									+ latitude + "," + longitude + "&output=json&pois=0";
							// HttpGet连接对象
							HttpGet httpRequest = new HttpGet(httpUrl);
							// 取得HttpClient对象
							HttpClient httpclient = new DefaultHttpClient();
							// 请求HttpClient,取得HttpResponse
							HttpResponse httpResponse = httpclient.execute(httpRequest);
							// 请求成功
							if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
								// 取得返回的字符串
								strResult = EntityUtils.toString(httpResponse.getEntity());
							}
						} catch (Exception e) {
							// TODO: handle exception
							e.printStackTrace();
						}

						// 解析json
						try {
							JSONTokener jsonParser = new JSONTokener(strResult);
							JSONObject js = (JSONObject) jsonParser.nextValue();
							JSONObject result = js.getJSONObject("result");
							formatted_address = result.getString("formatted_address");

						} catch (Exception e) {
							// TODO: handle exception
							e.printStackTrace();
						}
						
						mMainHandler.sendMessage(mMainHandler.obtainMessage(ADDRESS,
								formatted_address));
					
					
				}
				
			};
			Looper.loop();
		}
	}
}

skgary 2014-08-29
  • 打赏
  • 举报
回复
你这个为null ,估计没有new过吧?
skgary 2014-08-29
  • 打赏
  • 举报
回复
你这么一点代码段,完全没办法代人明白啊。 主线程要求网络线程干活,可以直接用notify或者用队列就可以了啊。 为什么还用用handler呢?

80,337

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧