2017-03-26 10 views
0

を投入しようとしたとき、私は、nullポインタ例外を取得しています(ここでは代わりに私の1をテストしている)アンドロイド - NullPointerExceptionがリスト

これは、それが呼び出された場所です方法

public String getLat(int i) { 
     fillDriverList(); 
     arrayLat.get(i); 
     return"0.000"; 

    } 

ですここでは別の活動でから

AdminActivity appState = new AdminActivity(); 
       latString = appState.getLat(i); 

ドライバ名をプリントアウトされたfillメソッドは、そのリストを埋めるように見えますが、その後、私のgetLat私の中でいくつかの理由でnullになっていますthod ??値が、私は次の中で、その後使用していますが、私はこの

intent.putStringArrayListExtra("arrayLat", arrayLat); 

ようにそれを渡す

public void fillDriverList() { 

     //Creating firebase object 
     Firebase ref = new Firebase(Config.FIREBASE_URL); 

     //adding a value event listener so if data in database changes it does in textview also not needed at the minute 
     ref.child("Driver").addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       arrayLat = new ArrayList<String>(); 

       for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
        Driver d = postSnapshot.getValue(Driver.class); 

        System.out.println("data snapshot Drivers name is -------------------> "+d.getName()); 

        arrayLat.add(Double.toString(d.getLat())); 


       } 

      } 

      /************had to implement this method****************/ 
      @Override 
      public void onCancelled(FirebaseError firebaseError) { 
       System.out.println("The read failed: " + firebaseError.getMessage()); 

      } 
     }); 

    } 

NOTE この

arrayLat = I.getStringArrayListExtra("arrayLat"); 

のような他のactvityでそれを使用して問題はありませんアクティビティは値が格納され、ファイアベース内の自分の情報(緯度)が変更されたときには更新されません。

おかげ

答えて

1

に肉眼を通して見えるという問題を、それをチェックする必要があり、リストはリスナーまたはコールバックに移入されている、ということです、あなたが扱っています全部同期している ルック

ref.child("Driver").addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       arrayLat = new ArrayList<String>(); 

       for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
        Driver d = postSnapshot.getValue(Driver.class); 

        System.out.println("data snapshot Drivers name is -------------------> "+d.getName()); 

        arrayLat.add(Double.toString(d.getLat())); 


       } 

      } 

      /************had to implement this method****************/ 
      @Override 
      public void onCancelled(FirebaseError firebaseError) { 
       System.out.println("The read failed: " + firebaseError.getMessage()); 

      } 
     }); 

あなたはOnDataChangeの内側arrayLatを移入されている(DataSnapshotスナップショット)

だから、実際にはこれがコールバックラインarrayLat.get(I)であることから、リスナーの前にさえ呼ばれていることである

こっちarrayLatが生成されます。あなたはそれを持っていますか? これにはいくつかの方法があります。 コールバックを処理する別のインターフェイスを作成することも、コールバック内にコードを直接書き込むこともできます。私は単純な解を書くだけです。 コードをこれに変更します。 最初のインターフェイスを作成し、

public interface SnapshotListener{ 
    void onListFilled(ArrayList<String> arrayLat); 
    void onFailure(); 
} 
    public void getLat(int i, SnapshotListener listener) { 
      fillDriverList(listener); 
      //arrayLat.get(i); 
      //return"0.000"; 

     } 

は今、これに他の方法を変更します。

public void fillDriverList(SnapshotListener listener) { 

     //Creating firebase object 
     Firebase ref = new Firebase(Config.FIREBASE_URL); 

     //adding a value event listener so if data in database changes it does in textview also not needed at the minute 
     ref.child("Driver").addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       arrayLat = new ArrayList<String>(); 

       for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
        Driver d = postSnapshot.getValue(Driver.class); 

        System.out.println("data snapshot Drivers name is -------------------> "+d.getName()); 

        arrayLat.add(Double.toString(d.getLat())); 


       } 
       if(listener != null){ 
        listener.onListFilled(arrayLat); 
       } 

      } 

      /************had to implement this method****************/ 
      @Override 
      public void onCancelled(FirebaseError firebaseError) { 
       System.out.println("The read failed: " + firebaseError.getMessage()); 
      if(listener != null){ 
        listener.onFailure(); 
       } 
      } 
     }); 

    } 

今符号この

appState.getLat(i, new SnapshotListener{ 
    public void onListFilled(ArrayList<String> arrayLat){ 
    AdminActivity appState = new AdminActivity(); 
        latString = arrayLat; 
} 
    public void onFailure(){ 
    //go crazy 
} 
}); 

AdminActivity appState = new AdminActivity(); 
       latString = appState.getLat(i); 

を変更直接SOで書かれているので、いくつかの構文エラーがあってもよいです。

+0

あなたが言っていることは、私がこの年齢に固執している答えのおかげで、感謝のようです。しかし、コードでいくつかのエラーを取得します。ほんの少しの質問。エラーは、私がappStateを作成しているコードの最後の部分にあります。 appState.getLat()を呼び出す前にappStateを作成する必要があります。また、新しいSnapshotListenerをAdminに変更する必要があります。snapshotListenerまたは別のクラスにインターフェイスを作成する必要はありますか? –

+0

latString = arrayLatのコードの最後の部分。しかし、1つはStringで、1つは配列なので、arrayLat.get(i)を意味すると思いますか?しかし、そのメソッドは何も返さないし、何かを返すようにすれば、まだ動作しません –

+0

申し訳ありませんが、latStringは文字列です。うん、あなたはlatString = arrayLat.get(i)を使う必要があります。別々のクラスは必要ありません。あなたはそれを行うことができますが、クラス内のどこにでも作成すればうまくいきます。あなたが親クラスの名前を知っているのであれば、私はそれがAdminならばもちろんAdmin.SnapshotChangeListenerです。この全体がコールバックに基づいているため、つまり、完了するために別のスレッドに依存しているため、何かを返すことはできません。適切なコードの構造化によって、あなたはそれを必要としません。関数が何かを返す場合、それは同期していなければなりません。私のポイントを得ていますか? – Debanjan

0

ドライバオブジェクトが

  for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
       Driver d = postSnapshot.getValue(Driver.class); 
       if(d!=null){ 
        arrayLat.add(Double.toString(d.getLat())); 
       } 
      } 
関連する問題