0

我一开始就深表歉意,因为我知道回答这个问题就像把果冻钉在墙上一样。我会提供尽可能多的细节,但没有太多可以提供的。

我正在开发一个黑莓应用程序,它使用 GPS 每 xx 分钟获取用户的位置(可能是 15、30 或 60,具体取决于用户设置的偏好);它将位置数据发送到 Web 服务。

它运行良好并报告用户的位置正常,但只有大约 16-18 小时,然后应用程序停止报告并且用户界面不再工作。不会抛出任何错误,它只是在重新启动应用程序之前不再响应用户选择。

令我感到奇怪的是,应用程序崩溃是相当可预测的——它永远不会在 8 小时或 10 小时后崩溃,它总是在 16-18 小时的窗口内,这表明崩溃与 GPS/WebService 有关报告。

基本上,如果我从 GPS/WebService 的角度来看,它看起来好像应用程序可以设法向 WebService 报告 36 次(每半小时,持续 18 小时),然后它就死了。

我将在这里发布一些代码,希望它能激发某人的想法。

private void updateGPSLocation(){
    gps_interval_timer.scheduleAtFixedRate(new TimerTask() {
       public void run() {
         try{

           getGPSLocation();
           if(longitude != 0.0 && latitude != 0.0)
           {
             updateSubscriberLocation();
           }

          }catch(Exception ex){                 
             }
      }
  }, 0, gps_interval);
}

这是前面代码中引用的 getGPSLocation() 调用的代码:

public void getGPSLocation(){
     try{
          //GPS thread
           BlackBerryLocationProvider provider = (BlackBerryLocationProvider)LocationProvider.getInstance(new BlackBerryCriteria(GPSInfo.GPS_MODE_ASSIST));

          //geolocation thread
           BlackBerryLocationProvider provider1 = (BlackBerryLocationProvider)LocationProvider.getInstance(new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE_CELL));

        if (provider != null){
            provider.setLocationListener(new LocationListenerImpl(), _interval, 1, 1);
         }

         if(provider1 != null){
            provider1.setLocationListener(new LocationListenerImpl(), _interval, 1, 1);
         }
      }
      catch(Exception le){
       }        
}

再次,我很抱歉,我知道这是一个开放式问题。Blackberry GPS 是否存在任何已知问题?因为我正在使用计时器任务来安排基于间隔的报告,所以我是否可能只是通过将计划的计时器任务放入队列中来吸收所有可用内存?我是否需要使用 cancel() 方法显式处理计时器任务?就像是:

gps_interval_timer.scheduleAtFixedRate(new TimerTask() {
       public void run() {
         try{

           getGPSLocation();
           if(longitude != 0.0 && latitude != 0.0)
           {
             updateSubscriberLocation();
           }

          }catch(Exception ex){                 
             }
          finally
          {
             this.cancel();
          }

      }
  }, 0, gps_interval);

非常感谢任何帮助。谢谢!

更新了 LocationListener 代码

private class LocationListenerImpl implements LocationListener { 
    public void locationUpdated(LocationProvider provider, Location location) {
    if(location.isValid()) {
       longitude = location.getQualifiedCoordinates().getLongitude();
       latitude = location.getQualifiedCoordinates().getLatitude(); 
     }
   }
    public void providerStateChanged(LocationProvider provider, int newState) {

    }
}

getGPSLocation() 中使用的 _interval 变量设置为 -1。

4

1 回答 1

1

我认为你需要重构你的代码。您正在使用计时器以 gps_interval 指定的速率创建 BlackBerryLocationProvider,它将以 _interval 指定的速率获取位置并调用 LocationListenerImpl 的 locationUpdated() 方法(您为每个 BlackBerryLocationProvider 创建新方法。至少存在两个潜在问题这里:

  1. 我怀疑 _interval 与 gps_interval 相关,在这种情况下,在 gps_interval 时间量之后,您创建一个位置提供程序,该提供程序在向侦听器提供位置之前等待 _interval 时间量。到这个时候,您的计时器可能再次过期,导致创建另一个位置提供程序......消耗了不必要的资源。
  2. 您还没有向我们展示您的 LocationListener 实现。如果您不关闭 BlackBerryLocationProvider 并释放 LocationListenerImpl,那么每次计时器到期时,您将创建消耗更多资源的新对象,而不会释放旧对象。

对 setLocationListener() 的调用具有间隔参数的原因之一是支持您想要执行的操作,即)定期提供位置。使用这个工具可以让操作系统更智能地了解它如何处理 GPS,如果使用不当,这会严重消耗电池电量。

因此,当您需要位置创建提供程序时,为所需的时间间隔注册您的侦听器,然后在侦听器中处理位置。请务必在单独的线程上连接到后端 Web 服务。如果您停止等待服务器响应的事件线程,您将给系统带来更多麻烦。

编辑:

这可能是满足您需求的 getGPSLocation() 的实现。它会尝试一组标准,然后是另一组。它仍然依赖于时间间隔的计时器,但不使用位置提供程序的时间间隔/回调属性。由于它没有注册侦听器,因此一旦提供者超出范围,它将受到垃圾回收的影响。

public void getGPSLocation(){
   try{
      //GPS thread
      BlackBerryLocationProvider provider =
         (BlackBerryLocationProvider)LocationProvider.getInstance(
         new BlackBerryCriteria(GPSInfo.GPS_MODE_ASSIST));

       if (provider != null){
          try {
             Location location = provider.getLocation(timeout);
             // process location
             return;
          } catch (LocationException le) {
          } catch (Exception e) {
          }
       }

       provider =
          (BlackBerryLocationProvider)LocationProvider.getInstance(
          new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE_CELL));

       if (provider != null){
          try {
             Location location = provider.getLocation(timeout);
             // process location
          } catch (LocationException le) {
          } catch (Exception e) {
          }
       }
    }
    catch(Exception le){
    }        
 }

话虽如此,更好的方法可能是将 updateGPSPosition 和 getGPSPositioin 替换为(来自 API 文档):

public void updateGPSPosition() {
   BlackBerryCriteria bbCriteria;
   BlackBerryLocationProvider bbProvider;

   try { //setup Criteria
      bbCriteria = new BlackBerryCriteria()); // use default mode on the device
      bbCriteria.enableGeolocationWithGPS();  // retrieve geolocation fix if GPS fix unavailable
   } catch (UnsupportedOperationException uoe) {}

   try { //setup LocationProvider
      bbProvider = (BlackBerryLocationProvider)LocationProvider.getInstance(bbCriteria);
      bbprovider.setLocationListener(new LocationListenerImpl(), interval, timeout, maxage);
   } catch (LocationException le) {}

}

您可能希望将 bbCriteria 和 bbProvider 保存在稍后可以获取它们以更改间隔或停止获取位置的地方。

很难找出在 providerStateChanged() 内部做什么,这是我通常使用的:

public void providerStateChanged(LocationProvider provider, int newState) {
    if (newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
    {
        if (unavailableCount < 3) {
            System.err.println("TEMPORARILY_UNAVAILABLE Reset " + Integer.toString(unavailableCount));

            // de-register listener, reset the provider and re-register
            locationProvider.setLocationListener(null, -1, -1, -1);
            locationProvider.reset();
            locationProvider.setLocationListener(this, 1, -1, -1);
            unavailableCount++;
        } else {
            System.err.println("TEMPORARILY_UNAVAILABLE Suspend");
            locationProvider.setLocationListener(null, -1, -1, -1);
        }
    }
    else if (newState == LocationProvider.AVAILABLE)
    {
        unavailableCount = 0;
    }
    else {
        System.err.println("OUT_OF_SERVICE");
        locationProvider.setLocationListener(null, -1, -1, -1);
    }
}
于 2012-04-10T15:11:03.110 回答