我正在尝试通过处理程序获取GPS坐标。以下是代码:
final Thread ObainGpsBackground = new Thread(new Runnable() {
@Override
public void run() {
try{
String SetServerString = "";
//Obtaining GPS co-ordinates :
LatLong obj_latLong = new LatLong(getActivity());
addressList = obj_latLong.getListAddressFromGeocoder(getActivity());
//Setting the addressList.getLatitude() into a variable "SetServerString"
for (Address address : addressList) {
SetServerString = String.valueOf(address.getLatitude());
threadMsg(SetServerString);
}
//Obtaining GPS co-ordinates :
}
catch(Throwable t){
Log.i("Exception","Getting GPS exception : "+t);
}
}
});
不知何故,代码总是朝着catch块导航。我得到这个错误:
I/Exception: Getting GPS exception : java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
这是处理程序:
private void threadMsg(String setServerString) {
if (!setServerString.equals("") && !setServerString.equals("0")) {
Message msgObj = handler.obtainMessage();
Bundle b = new Bundle();
b.putString("message", setServerString);
msgObj.setData(b);
handler.sendMessage(msgObj);
}
}
private final Handler handler = new Handler() {
public void handleMessage(Message msg) {
String aResponse = msg.getData().getString("message");
if ((null != aResponse)) {
// ALERT MESSAGE
// alert_attendance(getResources().getString(R.string.warning), getResources().getString(R.string.ects));
Toast.makeText(getActivity(), "Response: "+aResponse, Toast.LENGTH_SHORT).show();
}
else
{
// ALERT MESSAGE
alert_attendance(getResources().getString(R.string.warning), getResources().getString(R.string.unableToFindLocation));
// Toast.makeText(getBaseContext(), "Not Got Response From Server.", Toast.LENGTH_SHORT).show();
}
}
};
看过各种帖子。不知何故无法弄明白。如何准确实现looper.prepare()?有什么想法吗?
答案 0 :(得分:0)
这种情况正在发生,因为Looper
未创建和准备Thread
,而Handler
需要Looper
,因此它可以接收消息。如果没有看到完整的代码,就很难确定它,但实际上发生的事情是你的Handler
被创建时(当加载它所属的任何类时 - 看起来像threadMsg
}),这发生在你的自定义线程上。
如果您打算更新用户界面,我建议您更新Activity
或Fragment
代码,以公开基于GPS提供更新的公开方法。更好的封装方法是让你的GPS后台工作者定义一个接口,以便在事件发生时回调一些东西:
public interface GpsEventListener {
void gpsEventReceived(int type, String data);
}
让您的Activity
或Fragment
实现此界面并让他们创建将在主线程上运行的Handler
:
public class MyGpsActivity extends Activity implements ThreadMsg.GpsEventListener, Handler.Callback {
...
private Handler handler = new Handler(this);
public boolean handleMessage(Message msg) {
/* do work here */
}
public void gpsEventReceived(int type, String data) {
Message msg = Message.obtain(handler, type, data);
msg.sendToTarget();
}
}
在启动/停止后台线程以及与主线程交互时要非常小心。 Thread
对象无法识别生命周期,因此当您的Activity
或Fragment
暂停时,您无法再更新UI组件,并且您将要停止后台工作人员。
我还建议使用GPS数据的异步通知,而不是像这样轮询。否则你将使用大量的CPU和电池。