主线程和网络线程之间用handler传递数据时,handler空指针错误。已经快疯掉了。。。。 你这么一点代码段,完全没办法代人明白啊。主线程要求网络线程干活,可以直接用notify或者用队列就可以了啊。为什么还用用handler呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你这个为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(); } }} 你这里 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)); } } returnLocation()这个函数里面又定义了一个局部的mNetHandler?mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。 我建议 你子线程里只需要拿完,Post回主线程就可以了,主线程里收到相应的回复,把子线程的变量置空。主线程要取东西,判断一下子线程对像引用 是不是用为空,如果为空,则说明没有子线程在运行,直接再start一个子线程就好了。 我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决? 我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决? 你是纯为了学习呢?还是为了解决问题? 这个问题解决的一个常用方法是:打log看程序运行的情况,就可以直接的看到线程运行了没,变量为什么为空·~~~~~~~~~从楼主的回复中反映出,出现问题后解决问题时都是靠推测,而不是看实际的运行数据。 我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决? 你是纯为了学习呢?还是为了解决问题?解决问题 如果为了解决问题还不简单啊。子线程里就不要用handler了,run结束的时候,给主线程里的handler post消息即可。如果你还要再取别的内容,就再new/start一个子线程出来。 代码太乱了,纯粹死为了实现功能而实现功能毫无设计可言,这样造成的结果就是自己都不知道执行顺序是怎样的。你应当分开,网络请求放在一个类或者一个方法里面,handler里面只是执行更新UI线程的操作,Thread里面请求网络操作和通知handler更新界面。你为什么要在子线程中使用handler,而在handler里面又请求网络,这样会造成很多未知的错误,就像你的为null错误,因为线程的生命周期你是很难控制的。所以你应当让每个线程独立开来,不要相互影响。 android monkey截图出来不正确。 局域网内两台主机,一台(A)通过USB连接android设备,另一台(B)怎么用adb连接android设备? 如何禁止手机横屏? SQLlite删除操作问题 刚从java转android,有个关于static的小问题不理解. 如何为多个Button绑定同一个控件啊? 读取AndroidManifest.xml Android软键盘问题 安卓自动分页 Android中如何让Activity悬浮在手机屏幕上 android,SharedPreference问题 android logcat里的application字段为空
我在子线程里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();
}
}
}
而且就算你把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));
}
}
mNetHandler在另外一个thread里面建立,你要考虑同步,要等对象建立完才能去sendMessage啊。
我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决?
我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决? 你是纯为了学习呢?还是为了解决问题?
我在主线程和网络线程里都有handler,想这让实现来回通信。我昨天百度了很多之后,觉得可能是分线程里对象在建立之前执行了sendMessage,但这个问题怎么解决? 你是纯为了学习呢?还是为了解决问题?解决问题