Тост показывается даже после finish();

Я новичок в Android, и я нашел здесь похожий вопрос, но ни один из них не смог решить мою проблему. Приведенный ниже код в основном предназначен для получения двух двойных значений (широты и долготы) из Firebase и нанесения их на карту. Существует всплывающее уведомление, которое отображается, когда пользователь выходит из системы, то есть когда двойные значения были удалены из базы данных. Проблема здесь в том, что этот тост отображается даже после того, как я вернусь к другим занятиям. Как я могу остановить это. Я просто хочу закончить действие там, где я закончил.

Любая помощь будет оценена по достоинству. Заранее спасибо!

Изменить: если я открою много экземпляров этого действия (просмотр местоположений многих людей), я получу всплывающее уведомление о каждом экземпляре, когда каждый человек выйдет из системы. Я обеспокоен тем, что это приведет к потере большого количества ресурсов.

Может ли это быть из-за getMapAsync? Читал, что асинхронные задачи выполняются в другом потоке и не останавливаются даже после завершения().

Java-код:

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-код:

<?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>

person Shawn S. Thottan    schedule 24.06.2017    source источник
comment
посмотри мой ответ может поможет   -  person android_jain    schedule 24.06.2017


Ответы (5)


добавить финиш после в метод onDestroy()

 finish();
person AskNilesh    schedule 24.06.2017
comment
Я изменил коды. Тот, который я разместил, был другой активности. Перепутал. - person Shawn S. Thottan; 24.06.2017
comment
Пожалуйста, поделитесь исходным кодом первой активности в разделе startActivity. - person Ahmad Aghazadeh; 24.06.2017
comment
вы имеете в виду предыдущую активность? - person Shawn S. Thottan; 24.06.2017

Ваша проблема заключается в том, что прослушиватель не был удален, когда вы перешли к другому действию, за исключением случаев, когда вы нажали назад.

Вы должны поставить

myRef.removeEventListener (слушать);

В метод onPause/onStop. Поскольку ваш тост все еще жив, и любое изменение в дочернем элементе вызовет всплывающее уведомление.

person XepterX    schedule 24.06.2017
comment
Спасибо, но проблема не устранена, и проблема существует, даже когда я использую обратное нажатие. - person Shawn S. Thottan; 24.06.2017
comment
Что за тост вы видите? - person XepterX; 24.06.2017
comment
'@Override public void onChildRemoved(DataSnapshot dataSnapshot) { Toast.makeText(getApplicationContext(), username+ вышел из системы, Toast.LENGTH_SHORT).show(); myRef.removeEventListener (слушать); // android.os.Process.killProcess(android.os.Process.myPid()); финиш(); }' - person Shawn S. Thottan; 24.06.2017
comment
Извините, я спрашивал о тосте, который вы видите в другом действии, которое, как вы сказали, вызвано этим действием на карте. - person XepterX; 24.06.2017
comment
Вы разместили прослушиватель удаления над super.onStop или над super.onPause? - person XepterX; 24.06.2017
comment
Выше super.onPause и super.onStop. да. - person Shawn S. Thottan; 24.06.2017

Вы можете использовать ActivityName.this.finish();

person Sagar Patel    schedule 24.06.2017
comment
Вы можете использовать ToastName.cancel() Method.in метод onDestroy(). - person Sagar Patel; 24.06.2017
comment
Неа. Все еще ничего не изменилось. - person Shawn S. Thottan; 24.06.2017
comment
поместите Toastname.Cancel(); прежде чем закончить и попробовать. Вы отменяете все тосты этим методом. - person Sagar Patel; 24.06.2017
comment
Нужно ли создавать пользовательский вид, чтобы отменить Toast - person Sagar Patel; 24.06.2017

отмени свой тост перед завершением

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

и используйте это, когда вы звоните закончить.

testing.cancel(); 
 finish();

тост будет отображаться до тех пор, пока он не завершит выполнение, независимо от того, закрыта активность или нет. тост будет держаться 3 секунды (продолжительность сортировки). убедитесь, что вы звоните через 3 секунды или отмените тост и закончите вызов в любое время

person android_jain    schedule 24.06.2017
comment
и сделать переменную toast как globle - person android_jain; 24.06.2017
comment
Пробовал. Хотя никаких изменений. Точно такой же вывод. Тост.отмена(); ни на что не повлияло. - person Shawn S. Thottan; 24.06.2017
comment
использовать финишный метод после 3-х секундного использования обработчика - person android_jain; 24.06.2017

Тост отображается в течение продолжительности, соответствующей Toast.LENGTH_SHORT, что составляет 3,5 секунды в соответствии с это, независимо от того, активна вызывающая активность или нет. Я думаю, что вы хотите, чтобы показать тост, что пользователь вышел из системы. Подождите, пока он не появится на экране. Как только он закончит показ, уничтожьте активность. Этого можно добиться, вызвав show toast, подождав 3,5 секунды, а затем уничтожив активность. Итак, как описано здесь,

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

может работать.

В качестве альтернативы, если вы хотите дождаться продолжительности, отличной от 3,5 с или соответствующей Toast.LENGTH_LONG, следуйте это.

Редактировать: Извините, я неверно истолковал вашу проблему!

Я думаю, проблема может заключаться в том, что мы не можем отделить слушателя от его собственного метода. Я думаю, что вместо этого может быть полезно поставить myRef.removeEventListener(listen); в onDestroy().

person rushi    schedule 24.06.2017
comment
это имеет значение? Разве слушатель не должен перестать слушать, так как я использовал removeEventListener? - person Shawn S. Thottan; 24.06.2017
comment
О, теперь я получил ваш вопрос! (Ранее я думал, что тост продолжает отображаться в течение 3,5 секунд даже после уничтожения активности. Но кажется, что он появляется снова) Если это так, я обновлю свой ответ. - person rushi; 24.06.2017
comment
Я поместил это в onStop и onPause. Не решил проблему. - person Shawn S. Thottan; 24.06.2017
comment
finish() вызывает onDestroy() в соответствии с документами. Можешь попробовать вставить onDestroy()? - person rushi; 24.06.2017
comment
У вас есть @Override public void onDestroy() { super.onDestroy(); }, замените его на @Override public void onDestroy() {myRef.removeEventListener(listen); super.onDestroy(); } - person rushi; 24.06.2017