0

我正在尝试通过处理程序获取 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() ?有任何想法吗 ?

4

1 回答 1

0

发生这种情况是因为 noLooper是由创建和准备的Thread,并且Handler需要Looper它才能接收消息。在没有看到完整代码的情况下很难确定它,但本质上发生的事情是当你Handler被创建时(加载它所属的任何类时 - 看起来像threadMsg),这发生在你的自定义线程上。

如果您打算为此更新您的 UI,我建议更新您的ActivityFragment代码以公开一个公共方法以提供基于 GPS 的更新。更好的封装是让您的 GPS 后台工作人员定义一个接口以在事件发生时回调某些内容:

public interface GpsEventListener {
    void gpsEventReceived(int type, String data);
}

让您ActivityFragment实现此接口并让他们创建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对象不支持生命周期,因此当您的ActivityFragment被暂停时,您将无法再更新 UI 组件,并且您需要停止后台工作程序。

我还建议使用 GPS 数据的异步通知,而不是像这样轮询。否则你将使用大量的 CPU 和电池。

于 2016-07-12T12:14:51.063 回答