2

I am facing a problem in removing an Event Listener. I am using initialising a listener inside the onStart() in an Activity after collecting the user data, the app shows a toast to the user that the data has been uploaded and then I call the onBackPressed() method.

But I notice that the listener is still running after the activity is Paused or Stopped, because it is creating toast called under onCancelled() event.

So I tried overriding the onPause and onStop methods.

@Override
public void onPause() {
    super.onPause();
    // Remove post value event listener
      if (mListener != null) {
        mReadReference.removeEventListener(mListener);
       }
}  

But this is causing an error :

java.lang.RuntimeException: Unable to pause activity {deventree.com.thetimothyinitiative/deventree.com.thetimothyinitiative.Attendance}: java.lang.NullPointerException: listener must not be null

I want to remove the ValueEventListener after the data is uploaded and before the activity calls the onBackPressed() method

Code for Activity:

public class Attendance extends Activity {

Map<String, Boolean> td;
ArrayList<String> valu;


private SparseBooleanArray sbArray;

private static final String TAG = "Attendance";

CustomAdapter myAdapter;
ListView listview;

private DatabaseReference mReadReference;
private DatabaseReference mPostReference;
private ValueEventListener mListener;

private Button mButton;
private Button btnAll;
private Button btnNone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_attendance);

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    String eid=user.getEmail();
    System.out.println(eid);
    //String[] parts = eid.split("@");
    String[] parts = eid.split("\\.");
    eid = parts[0];
    System.out.println(eid);
    Date dNow = new Date( );
    SimpleDateFormat ft = new SimpleDateFormat("E dd-MM-yyyy 'at' HH:mm:ss");

     final ListView listview = (ListView) findViewById(R.id.listq);
    // Initialize Database
    mReadReference = FirebaseDatabase.getInstance().getReference()
            .child("Lists").child(eid);
    mPostReference = FirebaseDatabase.getInstance().getReference()
            .child("Users").child(eid).child(ft.format(dNow)).child("Attendance Record");

    //UI Elements
    btnAll=(Button)findViewById(R.id.button40);
    btnNone=(Button)findViewById(R.id.button33);
    mButton=(Button)findViewById(R.id.button42);

    btnAll.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            for (int i = 0; i < listview.getCount(); i++) {
                listview.setItemChecked(i, true);
            }
        }
    });
    btnNone.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int len=listview.getCount();
            int lou=listview.getChildCount();
            System.out.println(len+" "+lou);
            for ( int i=0; i < listview.getCount(); i++) {
                listview.setItemChecked(i, false);
            }
        }
    });

    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            System.out.println("Hello MF");
            SparseBooleanArray checked = listview.getCheckedItemPositions();
            for (int i=0; i<checked.size(); i++) {
                if (checked.valueAt(i)) {
                    String item = listview.getAdapter().getItem(checked.keyAt(i)).toString();
                    td.put(item, true);
                }
                else{
                    String item = listview.getAdapter().getItem(checked.keyAt(i)).toString();
                    td.put(item, false);
                     }
            }
            mPostReference.setValue(td);
            for (Map.Entry entry : td.entrySet()) {
                System.out.println(entry.getKey() + ", " + entry.getValue());
            }
            Toast.makeText(getApplicationContext(), "Attendance Uploaded",Toast.LENGTH_SHORT).show();
            onBackPressed();
        }
    });
}
@Override
public void onStart() {
    super.onStart();
    ValueEventListener mListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("here");
            td = (Map<String,Boolean>) dataSnapshot.getValue();
            for (Map.Entry<String, Boolean> entry : td.entrySet()) {
                td.put(entry.getKey(),false);
            }

            valu = new ArrayList<String>(td.keySet());
            ArrayAdapter<String> dataAdapter = new ArrayAdapter(getApplicationContext(), R.layout.rowview, valu);
            listview = (ListView) findViewById(R.id.listq);
            listview.setAdapter(dataAdapter);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
            Toast.makeText(Attendance.this, "Failed to load list.",
                    Toast.LENGTH_SHORT).show();

        }
    };
    mReadReference.addValueEventListener(mListener);
}

@Override
public void onStop() {
    // Remove post value event listener
    if (mListener != null) {
        mReadReference.removeEventListener(mListener);
        System.out.println("Doness");
    }
    super.onStop();

}

@Override
public void onPause() {

    // Remove post value event listener
    if (mListener != null) {
        mReadReference.removeEventListener(mListener);
        System.out.println("Here");
    }
    super.onPause();
}

}

srijanshukla
  • 1,066
  • 2
  • 13
  • 21

1 Answers1

5

Do it before super() calls. Like this :

@Override
public void onPause() {

    // Remove post value event listener
      if (mListener != null && mReadReference!=null) {
        mReadReference.removeEventListener(mListener);
       }
      super.onPause();
}  

Same for on Stop():

@Override
public void onStop() {

    // Remove post value event listener
    if (mListener != null && mReadReference!=null) {
        mReadReference.removeEventListener(mListener);
    }
    super.onStop();
}

EDIT 1 : Simply remove the declaration from onStart() Modify your onStart() like below code :

@Override
public void onStart() {
    super.onStart();

     // Removed  ValueEventListener mListener =new ValueEventListener() {

     mListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("here");
            td = (Map<String,Boolean>) dataSnapshot.getValue();
            for (Map.Entry<String, Boolean> entry : td.entrySet()) {
                td.put(entry.getKey(),false);
            }

            valu = new ArrayList<String>(td.keySet());
            ArrayAdapter<String> dataAdapter = new ArrayAdapter(getApplicationContext(), R.layout.rowview, valu);
            listview = (ListView) findViewById(R.id.listq);
            listview.setAdapter(dataAdapter);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
            Toast.makeText(Attendance.this, "Failed to load list.",
                    Toast.LENGTH_SHORT).show();

        }
    };
    mReadReference.addValueEventListener(mListener);
}

Just declare it above onCreate() or above onStart().

Hope this helps :)

Janki Gadhiya
  • 4,492
  • 2
  • 29
  • 59