繁体   English   中英

用户销毁应用程序时从onPause或onStop调用完成

[英]Call finish from onPause or onStop when the user destroys the app

结论: onDestroy() is not always being invoked.

就是这种情况:

启动应用程序后,将创建MainActivity ,它将启动后台跟踪服务。 另一方面,用户可以在主要活动中使用复选框列表来选择他感兴趣的路线,其中复选框列表中的各项代表路线。

单击提交按钮后,alarmManager开始每30秒将数据触发到IntentService类。 随后,在自动将用户重定向到MapActivity之后,建立与服务器的连接并开始向MapActivity检索数据。

用户可以使用两个活动菜单中的图标来停止和启动后台服务。 在下面所述的情况下,我面临销毁应用程序的问题。

使用当前代码:

  • 启动应用程序后,我可以在mainActivity中停止该服务,并销毁该应用程序。
  • 从主活动更改为地图活动后启动应用程序后,我可以停止并启动该服务以及通过打开Mapactivity销毁该应用程序。
  • 当我按照以下说明进行操作(mainActivity-> mapActivity-> MainAtivity-> MapActivity)并通过打开地图视图关闭该应用程序时,该应用程序未被破坏,该服务也未停止。 同样,MapActivity中的onDestroy()也不会被调用。 在这里,应用程序通过地图视图打开增益。

但是,当我执行以下操作时: bindService之后,在MapActivity bindService startService(i)(作为下面的四行代码段)添加到onStart()中,我可以销毁该应用程序以及停止和启动该服务,但是这里的问题是我没有我想每次从MainActivity转到MapActivity时都启动该服务,因为如果用户在MainActivity中停止该服务,则当他从主视图转到地图时它必须保持关闭状态。

@Override
protected void onStart() {
    super.onStart();
    // Bind to TrackingService.
    Intent intent = new Intent(this, TrackingService.class);
    bindService(intent, mConnection,    Context.BIND_AUTO_CREATE);            
    Intent i = new Intent(this, TrackingService.class);
    startService(i);
}

我知道无法保证何时在活动中调用onDestroy(),也许我应该在onPause()或onStop()内调用finish() (),但我的问题是如何知道何时在onPause()内调用finish()或onStop(),因为跟踪服务应在后台运行,直到该应用被用户破坏或用户决定使用菜单中的图标将其停止为止。 我不想在用户进入后台或每次调用onPause()时停止跟踪服务(以我为例,在一分钟内多次调用MapActivity中的onPause())。

仅当用户销毁应用程序时,如何才能从onPause()onStop()调用finish() 在这种情况下如何管理?

主要活动:

public class MainActivity extends ActionBarActivity implements
        AsyncTaskCallback {
boolean serviceStatus = true;
TrackingService mService;
boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.route_available);
        // Start the TrackingService class.
        Intent i = new Intent(this, TrackingService.class);
        startService(i);        

    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        System.out.println("ABC MainActivity onOptionsItemSelected was invoked.");
        switch (item.getItemId()) {
        case R.id.menu_toggle:

            if (serviceStatus) {
                item.setIcon(R.drawable.off);
                item.setTitle("OFF");
                serviceStatus = false;
                mService.stopTrackingService();
            } else {
                item.setIcon(R.drawable.on);
                item.setTitle("ON");
                serviceStatus = true;
                Intent i = new Intent(this, TrackingService.class);
                startService(i);
                System.out.println("ABC MainActivity onOptionsitemSelected   ON");
        }
        return super.onOptionsItemSelected(item);
    }
}

    @Override
    protected void onStart() {
        super.onStart();        
        // Bind to TrackingService.
        Intent intent = new Intent(this, TrackingService.class);            
        //To start the onPrepareOptionsMenue() after returning from the map activity to change the icon of the toggle button.
        invalidateOptionsMenu();

    }

    @Override
    protected void onStop() {
        super.onStop();
        //13.08.15
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            System.out.println("ABC MainActivity onStop() - unbindService(mConnection) was invoked. " + mBound);
            mBound = false;
        }else{
            System.out.println("ABC MainActivity onStop() - unbindService(mConnection) was invoked. " + mBound);
        }

    }
    @Override
    protected void onDestroy() {

        Intent i = new Intent(this, TrackingService.class); 
        stopService(i);

        mService.stopTrackingService();
    }
    private ServiceConnection mConnection = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;          
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;         
        }
    };

}

MapActivity

   public class MapActivity extends ActionBarActivity implements OnMapReadyCallback,
            ConnectionCallbacks, OnConnectionFailedListener {
         boolean serviceStatus;
        TrackingService mService;
        boolean mBound = false;

        @Override
        protected void onStart() {
            super.onStart();
                  serviceStatus = getIntent().getExtras().getBoolean("ServiceStatusExtras");
    if (serviceStatus) {
        Intent i = new Intent(this, TrackingService.class);
         bindService(i, mConnection, Context.BIND_AUTO_CREATE);
        startService(i);
        System.out.println("ABC MapActivity onStart serviceStatus = " + serviceStatus);
    }
        }

        /** Defines callbacks for service binding, passed to bindService() */
        private ServiceConnection mConnection = new ServiceConnection(){

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // We've bound to LocalService, cast the IBinder and get LocalService instance

                LocalBinder binder = (LocalBinder) service;
                mService = binder.getService();
                mBound = true;
                //System.out.println("ABC Map onServiceConnected() - " + mBound);

            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

                mBound = false;
                //System.out.println("ABC Map onServiceDisconnected() - mBound");

            }
        };
        @Override
        protected void onStop() {
            super.onStop();         
            if (mBound) {
                unbindService(mConnection);
                mBound = false;
            }       

        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            markerMap.clear();
            stopAlarm();

                    if(!serviceStatus){
        Intent i = new Intent(this, TrackingService.class); 
        stopService(i);
    }

        }
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case R.id.menu_toggle:

                if (serviceStatus) {
                    item.setIcon(R.drawable.off);
                    item.setTitle("OFF");
                    serviceStatus = false;
                    if(mService!=null){
                mService.stopTrackingService(); 
                }
                } else {
                    item.setIcon(R.drawable.on);
                    item.setTitle("ON");
                    serviceStatus = true;
                    Intent i = new Intent(this, TrackingService.class);
                    startService(i);
                }

            }
            return super.onOptionsItemSelected(item);
       }
    }

TrackingService类:

public class TrackingService extends Service implements AsyncTaskCallback,
        LocationListener {
LocationManager lm;
private final IBinder mBinder = new LocalBinder();

    @Override
    public IBinder onBind(Intent intent) {  
        return mBinder;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        detectLocation();
        return START_NOT_STICKY;
    }

    private void detectLocation() {
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 12 * 1000, 0,
                this);

    }
    public class LocalBinder extends Binder {
        TrackingService getService() {
            return TrackingService.this;
            }
       }

        public void stopTrackingService(){
        if(lm != null){
            lm.removeUpdates(this);
           }
        }

    }

}

一个经典的解决方案是拥有一个静态计数器,该计数器在每个活动“ onStart”上增加,而在“ onPause”上减少。

当计数器为0时,应用程序实际上已关闭

唯一困难的部分是,如果您对第一个活动的方向有所更改,因为活动已完全被系统破坏并重新创建,您可能会认为该应用程序确实已关闭(在这种情况下,计数器为0)

对于这种特殊情况,我没有神奇的解决方案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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