0

この質問に答えるのは、壁にゼリーを釘付けにするようなものだとわかっているので、最初から深くお詫び申し上げます。できる限り詳細をお伝えしますが、多くはありません。

GPS を使用して xx 分ごとにユーザーの位置を取得する Blackberry アプリを開発しています (ユーザーの設定に応じて、15、30、または 60 になる可能性があります)。位置データを Web サービスに送信します。

正常に動作し、ユーザーの位置を正常に報告しますが、約 16 ~ 18 時間しか経過せず、その後、アプリが報告を停止し、ユーザー インターフェイスが機能しなくなります。エラーはスローされません。アプリが再起動されるまで、ユーザーの選択に応答しなくなります。

アプリのクラッシュがかなり予測可能であることは奇妙です-たとえば、8時間または10時間後にクラッシュすることはありません。常に16〜18時間のウィンドウで発生します。これは、クラッシュがGPS / WebServiceに関連していることを示唆しています報告。

基本的に、GPS/WebService の観点から見ると、アプリが WebService に 36 回 (30 分ごとに 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

コードをリファクタリングする必要があると思います。タイマーを使用して、_interval で指定されたレートで位置を取得し、LocationListenerImpl の locationUpdated() メソッドを呼び出す gps_interval で指定されたレートで BlackBerryLocationProvider を作成しています (BlackBerryLocationProvider ごとに新しく作成します。少なくとも 2 つの潜在的な問題があります。ここ:

  1. _interval は gps_interval に関連していると思われます。この場合、gps_interval の時間の後、リスナーに場所を提供する前に _interval の時間を待機する場所プロバイダーを作成します。この時点で、タイマーが再び期限切れになり、別のロケーション プロバイダーが作成される可能性があります。必要以上のリソースを消費しています。
  2. あなたは LocationListener の実装を私たちに見せていません。BlackBerryLocationProvider を閉じずに LocationListenerImpl を解放しないと、タイマーが切れるたびに、古いオブジェクトを解放することなく、より多くのリソースを消費する新しいオブジェクトが作成されます。

setLocationListener() の呼び出しに interval 引数がある理由の 1 つは、実行したいことをサポートするためです。つまり、定期的に場所を提供します。この機能を使用すると、OS が GPS を処理する方法についてもう少しインテリジェントになることができます。

したがって、位置が必要な場合はプロバイダーを作成し、必要な間隔でリスナーを登録してから、リスナーで位置を処理します。必ず別のスレッドでバックエンド Web サービスに接続してください。サーバーが応答するのを待っているイベント スレッドを停止すると、システムにさらに問題が発生します。

編集:

これは、ニーズを満たす getGPSLocation() の実装である可能性があります。基準の 1 つのセットを試してから、もう 1 つの基準を試します。間隔は引き続きタイマーに依存しますが、ロケーション プロバイダーの間隔/コールバック プロパティは使用しません。リスナーを登録しないため、プロバイダがスコープ外になるとガベージ コレクションの対象になります。

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 と getGPSPositionin の両方を (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 に答える