【问题标题】:Using Location updates affects the main thread使用位置更新会影响主线程
【发布时间】:2016-12-21 00:10:02
【问题描述】:

我正在使用以下代码请求位置更新。在单独的处理程序线程中请求位置更新,但它仍然会影响主线程。任何人都可以提出一个解决方案。

private LocationListener mLocationListener = new LocationListener() {

    public void onLocationChanged(Location location) {

            mLongitude = location.getLongitude();
            mLatitude = location.getLatitude();
            mBearing = location.getBearing();

        }
}


mLocationManager = (LocationManager)
                this.getSystemService(Context.LOCATION_SERVICE);

HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();

Looper looper = handlerThread.getLooper();

mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                                    UPDATE_LOCATION_INTERVAL,
                                    UPDATE_LOCATION_MINIMUM_DISTANCE,
                                    mLocationListener, looper);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                    UPDATE_LOCATION_INTERVAL,
                                    UPDATE_LOCATION_MINIMUM_DISTANCE,
                                    mLocationListener, looper);

【问题讨论】:

  • 你怎么知道它会影响主线程?
  • 我正在使用主线程通过网络接收视频,它受到影响。当我禁用位置更新时它工作正常,但位置更新开始失败。
  • “我正在使用主线程通过网络接收视频”——这本身就很糟糕。不要在主应用程序线程上执行网络 I/O。您应该使用NetworkOnMainThreadException 崩溃。
  • 更准确地说,有一个监听器,在主线程中监听视频块。套接字连接、接收在不同的线程中处理,而不是在主线程中。

标签: android multithreading android-location android-handler


【解决方案1】:

最可能的问题似乎是当您调用Looper looper = handlerThread.getLooper(); 时,looper 还没有准备好。这最终使looper 为空,从而导致位置更新发生在主线程上。以下是有关 getLooper() 函数的更多信息。试试这个:

public class LocationThread extends HandlerThread {

    private static final long UPDATE_LOCATION_INTERVAL = 0;  //Set this to whatever you had it at
    private static final float UPDATE_LOCATION_MINIMUM_DISTANCE = 0.0f;  //Same with this

    private LocationManager mLocationManager;
    private LocationListener mLocationListener;

    public LocationThread(String name){
        super(name);
    }

    //Pass in your location manager and listener to this.  This assumes they are not null!
    public void startLocationUpdates(LocationManager locationManager, LocationListener locationListener){
        mLocationManager = locationManager;
        mLocationListener = locationListener;
        start();
    }

    //Use this to stop the updates and kill the thread.
    public void stopLocationUpdates(){
        if(mLocationManager != null){
            mLocationManager.removeUpdates(mLocationListener);
            mLocationListener = null;
            mLocationManager = null;
        }

        quit();
    }

    @Override
    protected void onLooperPrepared() {
        mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                                        UPDATE_LOCATION_INTERVAL,
                                        UPDATE_LOCATION_MINIMUM_DISTANCE,
                                        mLocationListener, getLooper());
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                        UPDATE_LOCATION_INTERVAL,
                                        UPDATE_LOCATION_MINIMUM_DISTANCE,
                                        mLocationListener, getLooper());
    }
}

对于此类,不要使用 start()quit() 函数,因为它们已在内部使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多