簡體   English   中英

帶有Firebase的Android-嘗試填充列表時出現NullPointerException

[英]Android with Firebase - NullPointerException when trying to populate list

我收到一個空指針異常(已經在這里測試了1而不是我)

這是方法

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

    }

這是在單獨的活動中調用它的地方

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

這是fill方法,它打印出驅動程序名稱,因此似乎正在填充列表,但是由於某種原因在我的getLat方法中為null?

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());

            }
        }); 

    }

注意當我這樣通過時

intent.putStringArrayListExtra("arrayLat", arrayLat);

在其他活動中使用它沒有問題

arrayLat = I.getStringArrayListExtra("arrayLat");

盡管我在下一個活動中使用的值是存儲的值,並且當Firebase中的信息(緯度)更改時不會更新。

謝謝

肉眼可見的問題是,列表是在偵聽器或回調中填充的,您將整個過程視為同步的。 看這里

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(DataSnapshot快照)中填充arrayLat

因此,事實是,由於這是一個回調,因此即使在激發偵聽器和填充arrayLat之前,也會調用arrayLat.get(i)行。 希望你明白了。 有幾種解決方法。 您可以創建另一個接口來處理回調,也可以直接在回調內部編寫代碼。 我將只寫一個簡單的解決方案。 將代碼更改為此。 首先創建一個界面,

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();
                }
            }
        }); 

    }

現在改變

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

對此

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

這些代碼直接用SO編寫,因此可能存在一些語法錯誤。

驅動程序對象必須檢查它

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM