简体   繁体   中英

Toast is shown even after finish();

I am new to android and I have found similar question here but none of it could solve my problem. The code below is basically to get two double values(latitude and longitude) from Firebase and plot them on the map. There is a toast that is shown when the user has logged out ie when the double values have been removed from the database. The problem here is that this toast is shown even after I go back to other activities. How can I stop this. I just want to end the Activity where I have put the finishes at.

Any help would be appreciated. Thanks in advance!

Edit: If I open many instances of this activity (View locations of many people) I would get the toast of every instance as each person logs out. I am concerned this would waste a lot of resources.

Could it be because of the getMapAsync? Have read that Async tasks run on a different thread and does not stop even after finish().

java code:

package com.example.android.managers;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class LocateS extends Activity implements OnMapReadyCallback {

    MapView mapView;
    GoogleMap googleMap;
    String username;
    int firstTime=0;
    LocationDetails loc;
    ChildEventListener listen = null;
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("Staff");

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

        Bundle extras = getIntent().getExtras();
        username= extras.getString("user");

        mapView = (MapView) findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this);

        listen = myRef.child(username).addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
                loc = dataSnapshot.getValue(LocationDetails.class);
                if(loc!=null)
                    setMap();
                else
                    Toast.makeText(getApplicationContext(),"Location not received yet",Toast.LENGTH_LONG).show();
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
                loc = dataSnapshot.getValue(LocationDetails.class);
                if(loc!=null)
                    setMap();
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                Toast.makeText(getApplicationContext(), username+" logged out", Toast.LENGTH_SHORT).show();
                myRef.removeEventListener(listen);
//                android.os.Process.killProcess(android.os.Process.myPid());
                finish();
            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}

            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });
    }

    public void setMap(){
        if(googleMap!=null){
            googleMap.clear();
            LatLng coordinate = new LatLng(loc.getLatitude(),loc.getLongitude());
            googleMap.addMarker(new MarkerOptions().position(coordinate));

            if(firstTime == 0) {
                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(coordinate, 17.0f);
                googleMap.moveCamera(cameraUpdate);
                firstTime++;
            }
        }
    }

    @Override
    public void onMapReady(GoogleMap map) {
        googleMap=map;
        map.getUiSettings().setZoomControlsEnabled(true);
    }

    @Override
    public void onResume() {
        mapView.onResume();
        super.onResume();
    }
    @Override
    public void onPause() {
        super.onPause();
    }
    @Override
    public void onStop(){
        finish();
        super.onStop();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    @Override
    public void onLowMemory() {
        mapView.onLowMemory();
        super.onLowMemory();
    }
    @Override
    public void onBackPressed() {
        myRef.removeEventListener(listen);
        finish();
//        android.os.Process.killProcess(android.os.Process.myPid());
        super.onBackPressed();
    }
}

xml code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.managers.Locate">

<com.google.android.gms.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"

    />

</RelativeLayout>

在onDestroy()方法之后添加完成

 finish();

Your issue is the listener was not removed when you moved to another activity except when you back pressed.

You should put the

myRef.removeEventListener(listen);

Into the onPause/onStop method. As your toast is still alive and any change to the child, it will trigger the toast.

The toast is shown for the duration corresponding to Toast.LENGTH_SHORT which is 3.5 sec according to this , no matter the calling activity is active or not. I think what you want is to show the toast that user had logged out. Wait till it is shown on screen. As soon as it is finished showing, destroy activity. This may be achieved by calling show toast, waiting for 3.5 sec and then destroying the activity. So, as described here ,

Toast.makeText(getApplicationContext(), username+" logged out", Toast.LENGTH_SHORT).show();
Thread thread = new Thread(){
    @Override
    public void run() {
        try {
            Thread.sleep(3500);
            LocateS.this.finish();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};
thread.start();

might work.

Alternatively, if you want to wait for duration other than 3.5 sec or that corresponding to Toast.LENGTH_LONG , follow this .

Edit: Sorry I misinterpreted your problem!

I think the problem might be that we cannot detach a listener from its own method. I think putting myRef.removeEventListener(listen); in onDestroy() instead might be helpful.

您可以使用ActivityName.this.finish();

cancel your toast before calling finish

   final Toast testing = Toast.makeText(context, "start.", Toast.LENGTH_SHORT);
    testing.show();

and use this when you r calling finish.

testing.cancel(); 
 finish();

toast will display until is will not complete execution no matter activity is closed or not. toast will tack 3 second(sort duration) . make sure you r calling after 3 second or cancel toast and call finish any time

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM