0

我有一个 AsyncTask 会调用

public static String getRequestURL(String urlName) {
    String url = "";
    if(GetUserLocation.userLocation == null){
        GetUserLocation gul = new GetUserLocation();

        LocationResult lResult = new LocationResult() {

            @Override
            public void gotLocation(Location location) {
                if(location != null) {
                    GetUserLocation.userLocation = location;
                }

            }
        };

        gul.getLocation(NLocateApplication.context, lResult);
        long timeOfLoad = Calendar.getInstance().getTimeInMillis();

        while(GetUserLocation.userLocation == null
                && Calendar.getInstance().getTimeInMillis() - timeOfLoad < 30000) {

        }
        Log.d("ServiceHelper.getRequestURL", "userlocation NULL");
    }

    url += ServiceHelpers.BASE_URL.toString() + urlName + "?"
            + "lattitude=" + GetUserLocation.userLocation.getLatitude()
            + "&longitude=" + GetUserLocation.userLocation.getLongitude()
            + "&type=" + Build.MANUFACTURER.toUpperCase() + "-" + Build.MODEL.replaceAll("\\s", "_")
            + "&uuid=" + NLocateApplication.UUID;

    return url;
}

doInBackground 方法中的方法。GetUserLocation 类将尝试获取用户位置。但有时我收到Can't create handler inside thread that has not called Looper.prepare()错误并且应用程序崩溃。

如何解决这个问题?任何帮助将不胜感激。

# 日志猫

java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:299) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask.setException(FutureTask.java:124) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.<init>(Handler.java:121) at android.app.Activity.<init>(Activity.java:772) at com.nepways.nlocate.location.GetUserLocation.<init>(GetUserLocation.java:16) at com.nepways.nlocate.helpers.ServiceHelpers.getRequestURL(ServiceHelpers.java:60) at com.nepways.nlocate.tasks.LocationsTask.getDataFromService(LocationsTask.java:127) at com.nepways.nlocate.tasks.LocationsTask.doInBackground(LocationsTask.java:78) at com.nepways.nlocate.tasks.LocationsTask.doInBackground(LocationsTask.java:1) at android.os.AsyncTask$2.call(AsyncTask.java:287) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) ... 5 more

获取用户位置.java

public class GetUserLocation {

private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1;
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 30000;

Timer timer1;

LocationManager locationManager = null;
LocationResult locationResult;
boolean gpsEnabled = false;
boolean networkEnabled = false;
public static Location userLocation = null;

public boolean getLocation(Context context, LocationResult result) {
    locationResult = result;

    if (locationManager == null) {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    }

    // exceptions will be thrown if provider is not permitted.
    try {
        gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {

    }

    try {
        networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    // don't start listeners if no provider is enabled
    if (!gpsEnabled && !networkEnabled)
        return false;

    if (gpsEnabled) {
        locationManager.removeUpdates(locationListenerGps);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
                MINIMUM_TIME_BETWEEN_UPDATES, 
                MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, 
                locationListenerGps);
    }

    if (networkEnabled) {
        locationManager.removeUpdates(locationListenerNetwork);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
                MINIMUM_TIME_BETWEEN_UPDATES, 
                MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, 
                locationListenerNetwork);
    }

    timer1 = new Timer();
    timer1.schedule(new GetLastLocation(), 30000);

    return true;
}

LocationListener locationListenerGps = new LocationListener() {


    @Override
    public void onLocationChanged(Location location) {
        timer1.cancel();

        locationResult.gotLocation(location);
        locationManager.removeUpdates(this);
        locationManager.removeUpdates(locationListenerNetwork);
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
};

LocationListener locationListenerNetwork = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        timer1.cancel();

        locationResult.gotLocation(location);
        locationManager.removeUpdates(this);
        locationManager.removeUpdates(locationListenerGps);
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
};

class GetLastLocation extends TimerTask {
    @Override
    public void run() {

        locationManager.removeUpdates(locationListenerGps);
        locationManager.removeUpdates(locationListenerNetwork);

        Location networkLocation = null, gpsLocation = null;
        if (gpsEnabled) {
            //t = Calendar.getInstance().getTimeInMillis();
            gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        }

        if (networkEnabled) {
            networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }

        // if there are both values use the latest one
        if (gpsLocation != null && networkLocation != null) {

            if (gpsLocation.getTime() > networkLocation.getTime())
                locationResult.gotLocation(gpsLocation);
            else
                locationResult.gotLocation(networkLocation);

            return;
        }

        if (gpsLocation != null) {
            locationResult.gotLocation(gpsLocation);
            return;
        }

        if (networkLocation != null) {
            locationResult.gotLocation(networkLocation);
            return;
        }

        locationResult.gotLocation(null);
    }
}

public static abstract class LocationResult {
    public abstract void gotLocation(Location location);
}

public void removeUpdates() {
    if(timer1!=null) {
        timer1.cancel();
    }
    locationManager.removeUpdates(locationListenerGps);
    locationManager.removeUpdates(locationListenerNetwork);
    userLocation = null;
    locationResult.gotLocation(null);
}

public Timer getTimer() {
    return this.timer1;
}}
4

1 回答 1

0

无法在未调用 Looper.prepare() 错误且应用程序崩溃的线程内创建处理程序。

很可能您正在从非起源(非 UI)线程但从后台/工作线程执行某些操作,UI这是不允许的。修复它应该可以解决您的问题。

于 2013-03-14T08:47:11.807 回答