最近做项目时出现个问题。
在一个基类中,创建一个Handler对象用于子线程向主线程发送数据--在准备支付页面PreparePayFragment创建了一个接口(接口是另一个应用支付应用中的类型),这个接口被调用最终也是在支付应用中运行的,但是这个接口中的方法调用了这个Handler(应该说是某个异步请求中的Handler)代码如下:
<span style="font-size:14px;">private CallbackListener cListener = new CallbackListener() {
@Override
public void callback(int responseCode, Bundle result) {
PayResultRequest request = new PayResultRequest(
mainActivity, shopSerialNumScd, msgCode) {
@Override
public void onPostExecute(Result result) {
String data = result.getData();
}
};
}
};
public MinaAsynTask(Context context, BaseRequestMessage requestMessage,int encrypt) {
this.requestMessage = requestMessage;
this.encrypt = encrypt;
this.context = context;
result = new Result();
basehandler = new BaseHandler(requestMessage, null, encrypt, 0);
//mhandler=new Handler(callback); //原先创建Handler的方法
mhandler = new Handler(context.getMainLooper(), callback);//修改后创建Handler的方法
}
private Handler.Callback callback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
onPostExecute(result);
return false;
}
};</span>
但不知道为啥一直报错:Can't create handler inside thread that has not called Looper.prepare()。
搜索后发现,原因是此Handler没有Looper。到哪儿去找Looper呢?自己建?
在代码前加入Looper.prepare();,心想这回可以了吧?
没想到依然报错,错误显示,一个主进程只能有一个Looper。
想到主进程中肯定有Looper,Context.getMainLooper(),再看Handler的实例化时是可以指定Looper的。
于是修改了创建Handler的方法,见第二段代码注释的两句代码。
修改后运行成功。
由于这段代码在项目中应用的场景比较复杂,网上有很多这个问题的处理方法,在此copy一段进行解释,
望原创作者谅解:
非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。
解决办法:
<span style="font-size:14px;">public void sendJson2Server(final JSONObject mJs) {
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
PushServiceEx.sendPublic(mTopicServer, mJs.toString());
System.out.println(mJs.toString());
}
};
mHandler.sendEmptyMessageDelayed(0, 5000);
// PushServiceEx.sendPublic(mTopicServer, mJs.toString());
}
new Thread() {
public void run() {
Looper.prepare();
mPst.startPushService();
mPst.sendJson2Server(qJson);//上线发消息给server
Looper.loop();
}
}.start();</span>
加上上面
Looper.prepare();
Looper.loop();