如何在选项卡之间保留本地服务 运行?
How to keep a local service running in between tabs?
我目前正在开发计步器应用程序。起初,我从一个 activity,PedometerActivity 开始。 activity 在后台启动了应该 运行 的服务,并绑定到它。代码很长,所以我只给出我认为对我的问题有帮助的部分。
//Bind service
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//binder to communicate with the service
PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;
mPedometerService = mBinder.getService();
mPedometerService.registerCallback(mCallback);
}
public void onServiceDisconnected(ComponentName className) {
mPedometerService = null;
}
};
private void startPedometerService() {
if (!isPedometerService) {
Log.v(TAG, "Start service");
isPedometerService = true;
//start service
Intent intent = new Intent(getApplicationContext(),
PedometerService.class);
startService(intent);
}
}
//Bind to the service
private void bindPedometerService() {
Log.i(TAG, "Bind service");
Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
}
//close connection with service
private void unbindPedometerService() {
Log.i(TAG, "Unbind service");
unbindService(mServiceConnection);
}
//Stop the service that had been started
private void stopPedometerService() {
Log.i(TAG, "Stop service");
if (mPedometerService != null) {
//stop service
Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
stopService(intent);
isPedometerService = false;
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
super.onResume();
startPedometerService();
bindPedometerService();
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop");
stopPedometerService();
}
public void onDestroy() {
super.onDestroy();
unbindPedometerService();
stopPedometerService();
}
在扩展服务
的服务class中
/*Local service binding*/
public class PedometerBinder extends Binder {
public PedometerService getService() {
return PedometerService.this;
}
}
/*A client is binding to the service with bindService()
* Returns the IBinder object received in
* ServiceConnection.onServiceConnected(ComponentName,IBinder)*/
@Override
public IBinder onBind(Intent intent) {
return new PedometerBinder();
}
然后我修改了我的应用程序,使 tablayout 具有 3 个选项卡,因此有 3 个片段。我将 PedometerActivity 中的代码粘贴到 PedometerFragment 中并对其进行了修改
//Bind service
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//binder to communicate with the service
PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;
mPedometerService = mBinder.getService();
mPedometerService.registerCallback(mCallback);
}
public void onServiceDisconnected(ComponentName className) {
mPedometerService = null;
}
};
private void startPedometerService() {
if (!isPedometerService) {
Log.v(TAG, "Start service");
isPedometerService = true;
//start service
Intent intent = new Intent(getActivity().getApplicationContext(),
PedometerService.class);
getActivity().startService(intent);
}
}
//Bind to the service
private void bindPedometerService() {
Log.i(TAG, "Bind service");
Intent intent = new Intent(getActivity(), PedometerService.class);
getActivity().bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
}
//close connection with service
private void unbindPedometerService() {
Log.i(TAG, "Unbind service");
getActivity().unbindService(mServiceConnection);
}
//Stop the service that had been started
private void stopPedometerService() {
Log.i(TAG, "Stop service");
if (mPedometerService != null) {
//stop service
Intent intent = new Intent(getActivity(), PedometerService.class);
getActivity().stopService(intent);
isPedometerService = false;
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
super.onResume();
startPedometerService();
bindPedometerService();
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop");
stopPedometerService();
}
public void onDestroy() {
super.onDestroy();
unbindPedometerService();
stopPedometerService();
}
问题是当我在选项卡之间切换时无法保持服务 运行ning。我正在使用 FragmentStatePagerAdapter,因此当我导航到最后一个选项卡时,第一个片段 (PedometerFragment) 被卸载。我已经能够在 onSaveInstanceState 中保存其他变量,但这似乎没有帮助,因为一切都重新启动了。
您正在使用 startService
,因此即使您的绑定组件被销毁,服务也不应停止。但是,您在 onStop()
中显式调用 stopPedometerService()
,当您的片段不再启动时调用它。
尝试简单地从片段中的 onStop()
和 onDestroy()
中删除 stopPedometerService()
。
参见:https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html
This version of the pager is more useful when there are a large number
of pages, working more like a list view. When pages are not visible to
the user, their entire fragment may be destroyed, only keeping the
saved state of that fragment.
您需要在Activity
class中绑定服务。然后您可以通过接口或 public 方法从任何附加的 Fragment
使用它。
我目前正在开发计步器应用程序。起初,我从一个 activity,PedometerActivity 开始。 activity 在后台启动了应该 运行 的服务,并绑定到它。代码很长,所以我只给出我认为对我的问题有帮助的部分。
//Bind service
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//binder to communicate with the service
PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;
mPedometerService = mBinder.getService();
mPedometerService.registerCallback(mCallback);
}
public void onServiceDisconnected(ComponentName className) {
mPedometerService = null;
}
};
private void startPedometerService() {
if (!isPedometerService) {
Log.v(TAG, "Start service");
isPedometerService = true;
//start service
Intent intent = new Intent(getApplicationContext(),
PedometerService.class);
startService(intent);
}
}
//Bind to the service
private void bindPedometerService() {
Log.i(TAG, "Bind service");
Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
}
//close connection with service
private void unbindPedometerService() {
Log.i(TAG, "Unbind service");
unbindService(mServiceConnection);
}
//Stop the service that had been started
private void stopPedometerService() {
Log.i(TAG, "Stop service");
if (mPedometerService != null) {
//stop service
Intent intent = new Intent(PedometerActivity.this, PedometerService.class);
stopService(intent);
isPedometerService = false;
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
super.onResume();
startPedometerService();
bindPedometerService();
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop");
stopPedometerService();
}
public void onDestroy() {
super.onDestroy();
unbindPedometerService();
stopPedometerService();
}
在扩展服务
的服务class中 /*Local service binding*/
public class PedometerBinder extends Binder {
public PedometerService getService() {
return PedometerService.this;
}
}
/*A client is binding to the service with bindService()
* Returns the IBinder object received in
* ServiceConnection.onServiceConnected(ComponentName,IBinder)*/
@Override
public IBinder onBind(Intent intent) {
return new PedometerBinder();
}
然后我修改了我的应用程序,使 tablayout 具有 3 个选项卡,因此有 3 个片段。我将 PedometerActivity 中的代码粘贴到 PedometerFragment 中并对其进行了修改
//Bind service
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//binder to communicate with the service
PedometerService.PedometerBinder mBinder = (PedometerService.PedometerBinder)service;
mPedometerService = mBinder.getService();
mPedometerService.registerCallback(mCallback);
}
public void onServiceDisconnected(ComponentName className) {
mPedometerService = null;
}
};
private void startPedometerService() {
if (!isPedometerService) {
Log.v(TAG, "Start service");
isPedometerService = true;
//start service
Intent intent = new Intent(getActivity().getApplicationContext(),
PedometerService.class);
getActivity().startService(intent);
}
}
//Bind to the service
private void bindPedometerService() {
Log.i(TAG, "Bind service");
Intent intent = new Intent(getActivity(), PedometerService.class);
getActivity().bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
}
//close connection with service
private void unbindPedometerService() {
Log.i(TAG, "Unbind service");
getActivity().unbindService(mServiceConnection);
}
//Stop the service that had been started
private void stopPedometerService() {
Log.i(TAG, "Stop service");
if (mPedometerService != null) {
//stop service
Intent intent = new Intent(getActivity(), PedometerService.class);
getActivity().stopService(intent);
isPedometerService = false;
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
super.onResume();
startPedometerService();
bindPedometerService();
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop");
stopPedometerService();
}
public void onDestroy() {
super.onDestroy();
unbindPedometerService();
stopPedometerService();
}
问题是当我在选项卡之间切换时无法保持服务 运行ning。我正在使用 FragmentStatePagerAdapter,因此当我导航到最后一个选项卡时,第一个片段 (PedometerFragment) 被卸载。我已经能够在 onSaveInstanceState 中保存其他变量,但这似乎没有帮助,因为一切都重新启动了。
您正在使用 startService
,因此即使您的绑定组件被销毁,服务也不应停止。但是,您在 onStop()
中显式调用 stopPedometerService()
,当您的片段不再启动时调用它。
尝试简单地从片段中的 onStop()
和 onDestroy()
中删除 stopPedometerService()
。
参见:https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html
This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment.
您需要在Activity
class中绑定服务。然后您可以通过接口或 public 方法从任何附加的 Fragment
使用它。