【问题标题】:using asynTask to update LocationListener使用 asynTask 更新 LocationListener
【发布时间】:2014-01-03 03:58:39
【问题描述】:

我已经在这个论坛中寻找 aswer 但没有工作,我正在创建一个 android 应用程序并试图从 asyncTask 中的 locationlistener 获取坐标更新(我的 asyncTask 工作只是为了更新纬度和经度) 虽然主线程通过位置管理器从 asyncTask 获取坐标,并且它昨天工作,今天它不再工作了, 这是我的 asyncTask 代码:

 private class LoopMsg extends AsyncTask<String,Void,Void>{
        protected Void doInBackground(String... urls){

            Looper.prepare();

            LocationListener listen = new LocationListener() {

                @Override
                public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderEnabled(String arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onProviderDisabled(String arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onLocationChanged(Location loc) {
                    // TODO Auto-generated method stub

                    Log.d(TAG,"Latitude :"+String.valueOf(loc.getLatitude()));
                    Log.d(TAG,"Longitude :"+String.valueOf(loc.getLongitude()));
                    Glatitude = loc.getLatitude();
                    Glongitude = loc.getLongitude();
                }
            };          
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen);
            Looper.loop();


            return null;

        }
    }

请帮助我这里出了什么问题?以及如何解决这个问题?它之前运行良好 第二天我在 Looper.prepare() 遇到了异常 它说每个线程只能创建一个looper,然后我删除Looper.prepare和Looper.loop部分,错误更改变为

*FATAL EXCEPTION: asyncTask #1
*java.lang.RuntimeException: an error occured while executing do in background

我真的不知道为什么,因为我没有在我的 doInBackground 方法中更新 ui 线程

为什么我知道我的应用程序不工作: 1.onLocationChanged 不再调用 2.如果我不使用looper.prepare和looper.loop,应用程序崩溃

我也试过这样:

lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen, Looper.getMainLooper());

还有这个:

Looper.Mylooper.prepare();
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen, Looper.getMyLooper());

但仍然没有运气,应用程序仍然没有运行

这是我在 AsyncTask 中移除 Looper 后得到的 logCat(并且应用总是崩溃)

-Fatal Exception: AsyncTask#2
-java.lang.RuntimeException: An error occured while executing doInBackground()
-at android.os.AsyncTask$3.done(AsyncTask.java:299)
-at java.util.concurrent.FutureTask.finishCompletion(FutureTask.Java:219)
-at java.util.concurrent.FutureTask.run(FutureTask.Java:239)
-at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
-at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
-at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
-at java.lang.Thread.run(Thread.java:838)
-Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not  called Looper.prepare()
-at android.os.Handler.<init>(Handler.java:197)
-at android.os.Handler.<init>(Handler.java:111)
-at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:199)
-at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:199)
-at android.location.LocationManager.wrapListener(LocationManager.java:822)
-at android.location.LocationManager.requestLocationUpdates(LocationManager.java:835)
-at android.location.LocationManager.requestLocationUpdates(LocationManager.java:432)
-at android.location.ZTEPrivacyLocationManager.requestLocationUpdates(ZTEPrivacyLocationManager.java:107)
-at com.login.absen.MyService$LoopMsg.doInBackground(MyService.java:244)
-at com.login.absen.MyService$LoopMsg.doInBackground(MyService.java:1)
-at android.os.AsyncTask$2.call(AsyncTask.java:287)
-at java.util.concurrent.FutureTask.run(FutureTask.java:234)
-... 4 more

更新

我是客人,我可以将问题简单化 实际上问题是在 (zte n986 - android 4.2) 未调用 onLocationChange 方法,我在另一台设备 (journey - android 2.3.3) 中尝试此代码,行为是相同的,asyncTask 也停止在 Looper.loop 但 onLocationChange 运行方法正在运行,因此位置更新仍在运行

【问题讨论】:

  • 你不应该需要LooperAsyncTask,AFAIK。发布删除 Looper 代码时获得的完整异常。
  • 正确。如果您已经在使用AsynTask,则不需要Looper
  • @codeMagic 和@ChuongPham 如果我移除looper 应用程序将在服务开始运行时立即崩溃,这是为什么呢?
  • 因为AsyncTask需要从主Thread调用。你不应该为此需要AsyncTask
  • 我试过不使用 asyncTask,所以我做了一个方法 protected void updateLoc() {},这个方法包含与 asyncTask 类相同的代码,当然我需要使用 Looper.prepare和 Looper.loop ,问题发生在这里: lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listen); Looper.loop(); -> 这是到达 Looper.loop 时的问题,应用程序只会一遍又一遍地运行监听器方法,而主线程永远不会完成运行(我将监听器放在应用程序的中间),如何解决这个问题?

标签: android android-asynctask android-location


【解决方案1】:

首先不需要 AsyncTask 来监听位置更新。 LocationLintener 本身是异步运行的,所以只需注册位置更新并在

中更新 ui
 public void onLocationChanged(Location loc) {
                    // TODO Auto-generated method stub


                }

【讨论】:

  • 我做过,在我使用 asyncTask 之前,我只是调用了一个具有位置侦听器的函数,它给出了异常 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare,并且当我给 looper 时,它会给出异常“每个线程只能创建一个 looper”,这就是为什么我决定使用 asyncTask 来避免该异常,因为作为服务背景,这个函数将被一次又一次地调用,我认为这就是异常“每个线程只能创建一个活套”的原因
  • 我不这么认为。不需要任何其他步骤来收听位置更新。如果你愿意,我会准备一些代码来为每个位置更新做一个显示祝酒词。
  • 如果您担心LocationListener 课程会消耗一些电池电量,请使用AlarmManager 将您的任务安排在特定时间。
  • @CoolMonster at onLocationChanged 方法我已经在使用日志,所以如果运行日志的 onLocationChanged 方法将写入 logCat,并且不需要 Toast,它将每 1 分钟写入纬度和经度值将由位置管理器获取并发送到服务器,但由于 onLocationChanged 方法从未调用它,因此不会更新经纬度,如果我处于调试模式,调试将在 Looper.loop() 处停止
  • 您是使用设备测试此代码还是模拟器。
【解决方案2】:

使用服务,你可以在那里使用 Location Listner,没有 ne

【讨论】:

  • 整个应用程序作为 backgroundService 在后台运行
  • 好的,我正在使用主要部分的服务,它一遍又一遍地运行获取mac地址,ssid等,还获取位置(纬度和经度),这个位置需要更新我让它更新每 1 分钟 (locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 0, listener);) 所以我让 asyncTask 运行监听器,因为如果我在同一个地方运行监听器,它会出现异常
【解决方案3】:
public class LocateDeviceService extends Service {

private static final String TAG = "";

double lat = 0;
    double lng = 0;



@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    customHandler.postDelayed(updateTimerThread, 0);
    return super.onStartCommand(intent, flags, startId);
}

private Handler customHandler = new Handler();

private Runnable updateTimerThread = new Runnable() {

    public void run() {
        try {
            //send location

    LocationManager locman = (LocationManager) context
            .getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    String provider = locman.getBestProvider(criteria, false);
    Location location = locman.getLastKnownLocation(provider);

    if (location != null) {
        lat = location.getLatitude();
        lng = location.getLongitude();

    }

            customHandler.postDelayed(this,60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

};



public void sendLocationToServer(Double lat,Double lng )
        throws InterruptedException {
    //do ur job here

}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    if (null != customHandler && null != updateTimerThread) {
        customHandler.removeCallbacks(updateTimerThread);
    }
}
}

【讨论】:

  • 当你启动 LocateDeviceService 时,它​​会在每 1 分钟内不断更新你的位置,一旦你停止服务,它就会停止更新,试试吧,对我来说它有效
  • 阿米特,你能解释一下如何更新位置吗?虽然它没有 locationListener?现在我也得到了位置,只有位置没有更新,因为监听器没有运行
【解决方案4】:

AsyncTask 无需获取位置更改。位置可以发送到您在主线程上运行的注册类。如果您想将位置上传到服务器,则仅对该部分使用 AsynTask。

以下是步骤:
1. 在扩展服务的类上实现“LocationListener”。
2.然后需要实现LocationListener中未实现的方法。传递给您的位置是:

@覆盖 公共无效onLocationChanged(位置位置){ //只使用AsyncTask上传位置信息 uploadLocationToServerThroughAsyncTask(location); }


3. 现在,向 LocationManager 注册,以便在位置发生更改时将位置发送到您的班级,如下所示:

lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 标准标准 = 新标准(); 标准.setAccuracy(标准.ACCURACY_COARSE); 字符串提供者 = lm.getBestProvider(criteria, true); if (provider == null || provider.trim().isEmpty()) { // 没有提供者因此返回。 返回; } // 如果有任何可用的提供者,则注册位置更新。 lm.requestLocationUpdates(locProvider, 1000, 200, this); // 1 秒和 200 米更新



4. 在适当的时间从位置管理器中取消注册,如下所示:

尝试 { lm.removeUpdates(这个); } 捕捉(异常 e){ e.printStackTrace(); }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多