我正在我的应用程序中执行Foreground服务,当我在服务中调用方法Stopself
时,它正在调用我的OnDestroy
方法,但它并没有终止我的服务。它仍然使用内存,我通过adb shell dumpsys meminfo
检查它。
我试图从我的应用程序中调用StopService但它不起作用。我从其他人那里读了很多同样问题的帖子,但是他们在服务中使用了Handler。在我的情况下,我使用Singleton ThreadPool管理器管理所有内容,当应用程序关闭时,我已使用shutdown()
方法关闭。
当我关闭应用程序并且我的服务仍然有效时,就发生了这种情况。例如:
如果我录制了一段Fastmotion视频,我等到它处理完毕,之后我关闭了我的应用程序。我没有这段记忆。但是,如果我关闭应用程序然后服务正在处理它,它完成处理,但我有一个内存领先,因为服务器没有被杀死。
所以,希望有人可以看到它失败的地方,或者我可以改变什么来使这项工作。这是我的服务代码:
/*
Base Service is a abstract class which implement the concurrent methods for the different services of the app
*/
public abstract class BaseService extends Service {
private static final String TAG = "BaseService";
private static final int NOTIFICATION_ID = 10;
private Notification mNotification;
private boolean mIsNotificationShow = false;
/**
* mIsRegistered boolean controls when the application is in background or not.
* Is set to true in {@link @ServiceConnection method}
* Is set to false in {@link @unbindMediaSaveService()}
*/
protected boolean mIsRegistered = false;
/**
* Count the number of request in the service to show the notification
* and hide it when all of them are over
*/
protected int mNotificationCount = 0;
protected synchronized void showNotification() {
mNotificationCount++;
// Notification already shown.
if (mIsNotificationShow)
return;
if (mNotification == null) {
Bitmap bigIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
mNotification = new Notification.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(getResources().getString(R.string.string_processing_notification_service))
.setSmallIcon(R.drawable.ic_menu_savephoto)
.setLargeIcon(bigIcon).build();
}
startForeground(NOTIFICATION_ID, mNotification);
mIsNotificationShow = true;
}
protected synchronized void hideNotification() {
mNotificationCount--;
// Notification already hidden.
if (!mIsNotificationShow)
return;
if (mNotificationCount == 0) {
stopForeground(true);
mIsNotificationShow = false;
tryToCloseService();
}
}
/**
* Set IsRegistered boolean to true or false to check in the service when the application is in background or not
*
* @param register set the boolean value
*/
public void registerServiceClient(boolean register) {
mIsRegistered = register;
Log.i(TAG, "[registerServiceClient] Client registered: " + register);
if (!register) {
tryToCloseService();
}
}
/**
* Try to close the current service. It will be close if the application is in background{@link #mIsRegistered}
* and the service don't have current actions{@link #mNotificationCount}
*/
public void tryToCloseService() {
Log.i(TAG, "[tryToCloseService] Trying to close Service");
if (!mIsRegistered && mNotificationCount == 0) {
Log.i(TAG, "[tryToCloseService] Service stopped");
stopSelf();
} else {
Log.i(TAG, "[tryToCloseService] pending actions " + mNotificationCount);
}
}
}
我初始化一个ServiceConnection并在我的活动中绑定服务:
private ServiceConnection mMediaSaveConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder b) {
mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
m
MediaSaveService.registerServiceClient(true);
}
@Override
public void onServiceDisconnected(ComponentName className) {
if (mMediaSaveService != null) {
mMediaSaveService.setListener(null);
mMediaSaveService.setPhotoListener(null);
mMediaSaveService = null;
}
}
};
private void bindMediaSaveService() {
Intent intent = new Intent(this, MediaSaveService.class);
startService(intent);
if (mMediaSaveConnection != null) {
bindService(intent, mMediaSaveConnection, Context.BIND_AUTO_CREATE);
mMediaSaverIsBind = true;
}
}
private void unbindMediaSaveService() {
if (mMediaSaveService != null) {
mMediaSaveService.registerServiceClient(false);
}
if (mMediaSaveConnection != null && mMediaSaverIsBind) {
unbindService(mMediaSaveConnection);
mMediaSaverIsBind = false;
}
}
最后,我在我的onStart
/ onStop
我的活动中调用此方法。此外,如果它可以提供帮助,在我扩展我的BaseService的服务中,我放置一个START_NOT_STICKY
标志,以便在它被杀死时不重新创建服务。