【发布时间】:2015-09-23 22:01:21
【问题描述】:
启动应用程序后,会创建MainActivity,它会启动后台跟踪服务。另一方面,用户可以使用主活动中的复选框列表来选择他感兴趣的路线,其中复选框列表中的项目代表路线。
点击提交按钮后,alarmManager 开始每 30 秒将数据发送到IntentService 类。随后,与服务器建立连接,并在用户重定向到MapActivity 后开始向MapActivity 检索数据。
用户可以通过使用两个活动菜单中的图标来停止和启动后台服务。在下面描述的情况下,我面临销毁应用程序的问题。
使用当前代码:
- 启动应用后,我可以在 mainActivity 中停止服务并销毁应用。
- 当我从主Activity切换到地图Activity时启动应用程序后,我可以停止和启动服务以及通过打开MapActivity来销毁应用程序。
- 当我按照以下步骤 (mainActivity->mapActivity->MainAtivity->MapActivity) 并关闭应用程序并打开地图视图时,应用程序不会被破坏,服务也不会停止。 MapActivity 中的
onDestroy()也没有被调用。此处应用再次打开并显示地图视图。
但是当我执行以下操作时:
在bindService 之后将 startService(i)(作为代码 sn-p 下面的四行)添加到 MapActivity 中的onStart() 我可以销毁应用程序以及停止和启动服务但这里的问题是我不想每次我从 MainActivity 转到 MapActivity 时启动服务,因为如果用户在 MainActivity 中停止服务,当他从 main 转到地图时它必须保持关闭。
@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);
}
在这种情况下,如何在 MapActivity 中销毁应用程序? MainActivity:
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;
}
};
}
地图活动
public class MapActivity extends ActionBarActivity implements OnMapReadyCallback,
ConnectionCallbacks, OnConnectionFailedListener {
boolean serviceStatus;
TrackingService mService;
boolean mBound = false;
@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);
}
/** 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();
Intent i = new Intent(this, TrackingService.class);
stopService(i);
mService.stopTrackingService();
}
@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;
mService.stopTrackingService();
System.out.println("ABC Map onOptionsitemSelected OFF");
} 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);
}
}
}
}
【问题讨论】:
-
我能想到的快速解决方案是在服务中跟踪绑定元素的数量(在这种情况下为活动),当数量达到 0 时服务会自行停止?或者从应用程序类启动服务,并在应用程序调用关闭时关闭它
-
@DanielMendel:我如何计算绑定的元素?