2012-04-10 13 views
0

私はこの質問に答えることが壁にジェロを釘付けするようなものになることを知っているので、私は最初から丁寧に謝っています。私はできるだけ多くの細部を与えますが、与えるべきことはあまりありません。ブラックベリーのアプリケーション開発 - アプリケーションが16-18時間後に動作しなくなる

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に設定されています。

+1

私はあなたがキャッチされているすべての可能な例外をログに記録するブラックベリーEventLoggerクラスを使用することによって開始しますあなたが私たちに示したコードで、Thread.activeCount()と組み合わせて、決して終了しないスレッドをあまりにも多く開始していないことを確認してください。解決できない例外がスローされた場合は、ここに報告してください。 – paulkayuk

答えて

1

あなたのコードを再調整する必要があると思います。タイマーを使用してgps_intervalで指定されたレートでBlackBerryLocationProviderを作成しています。これは、_intervalで指定された速度で位置を取得し、LocationListenerImplのlocationUpdated()メソッドを呼び出します(BlackBerryLocationProviderごとに新規作成します)。ここに:

  1. 私はあなたがリスナーに場所を提供する前に、時間の_interval量を待つロケーションプロバイダを作成する時間のgps_interval量の後、その場合には、_intervalがgps_intervalに関連している疑いがある。この時点で、あなたのタイマーは、おそらく持っています。もう一度期限切れになり、別のロケーションプロバイダが作成される...必要以上のリソースを消費する
  2. あなたのLocationListenerの実装は表示されていませんに。 BlackBerryLocationProviderを終了してLocationListenerImplを解放しないと、タイマーの有効期限が切れるたびに、古いものを解放せずに、より多くのリソースを消費する新しいオブジェクトを作成します。

setLocationListener()の呼び出しにinterval引数がある理由の1つは、実行したいことをサポートすることです。つまり、定期的に場所を指定することです。この機能を使用すると、GPSをどのように処理するかについて、OSをより知的にすることができます。これは、不適切に使用された場合、バッテリを大幅に消耗します。

ポジションが必要な場合は、プロバイダーを作成し、必要な間隔でリスナーを登録してから、リスナー内のロケーションを処理します。別のスレッドでバックエンド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){ 
    }   
} 

は、より良い方法は、(APIドキュメントから)の両方updateGPSPositionとgetGPSPositioinを交換するかもしれないと言った:

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); 
    } 
} 
+0

LocationListener()実装の追加コードで質問を更新しました。 BlackberryLocationProviderを作成するたびに多くのリソースを消費していることを示唆していますが、これが18時間後にクラッシュする原因になります。 – JMax2012

+0

短い答え:はい。長い答え:実際には、タイマーが起動するたびに、2つのロケーションプロバイダと2つのロケーションリスナーを作成しているようです。それは一つの問題かもしれません。 BlackBerryデバイスはメモリが不足していることはよく知られていますが、もう1つの問題はシステムで使用できるObjectリファレンスの数です。いずれかが使い果たされ、他のアプリケーションが何かをあげることができない場合、システムは飢えています。他のいくつかの問題が原因で問題が発生している可能性がありますが、あなたが提供したコードからは結論です。 – Richard

+0

ご確認いただきありがとうございます。私はBlackberryの開発には非常に新しいので、ここに私のフォローアップの質問があります:もし私がこれらのBBプロバイダオブジェクトを明示的に処分すれば、クラッシュの問題を修正するでしょうか?これらのオブジェクトを処分する最良の方法は何ですか? (私が言ったように、私はBBの開発に新しいです。) – JMax2012

関連する問題