无法在后台获取GPS坐标(使用处理程序) - Android

时间:2016-07-12 10:45:33

标签: java android java-threads android-looper

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

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为Looper未创建和准备Thread,而Handler需要Looper,因此它可以接收消息。如果没有看到完整的代码,就很难确定它,但实际上发生的事情是你的Handler被创建时(当加载它所属的任何类时 - 看起来像threadMsg }),这发生在你的自定义线程上。

如果您打算更新用户界面,我建议您更新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和电池。