我使用服务在后台运行CountDownTimer
来创建应用程序。
但是,当应用程序关闭/终止时,后台服务有时会自行失败或停止。
我尝试使用START_STICKY
或START_NOT_STICK
,但仍然无法正常工作,无法使服务CountDownTimer
保持活动状态。 (this the different of them)
我也尝试了我在stackoverflow上发现的所有建议,但同样没有用。
这是我的代码:
SessionTimerService.java
public class SessionTimerService extends Service{
private CountDownTimer countDownTimer;
public static boolean isServiceRunning = false;
@Override
public void onCreate() {
super.onCreate();
startTimer();
}
@Override
public void onDestroy() {
isServiceRunning = false;
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent!=null && intent.getAction().equals(Constant.ACTION_START_SERVICE)){
startTimer();
}else{
stopTimer();
}
return START_STICKY;
}
private void stopTimer(){
stopForeground(true);
stopSelf();
isServiceRunning = false;
}
private void startTimer(){
if(isServiceRunning)return;
isServiceRunning = true;
String formatCountDown = "%02d:%02d:%02d";
countDownTimer = new CountDownTimer(TimeUnit.MINUTES.toMillis(1), 1000){
@Override
public void onTick(long millisUntilFinished) {
String time = ""+String.format(formatCountDown,
TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
Timber.d("The Time : " + time);
Intent broadcast = new Intent(Constant.EVENT_SESSION_TIMER);
broadcast.putExtra(Constant.BROADCAST_TIMER, time);
LocalBroadcastManager.getInstance(App.getInstance().getApplicationContext()).sendBroadcast(broadcast);
}
@Override
public void onFinish() {
Toast.makeText(SessionTimerService.this, "Timer ended!", Toast.LENGTH_SHORT).show();
}
};
countDownTimer.start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
App.java
我从应用程序启动CountDownTimer
。这里的代码:
public class App extends Application {
private ApplicationComponent applicationComponent;
private static boolean isChatActivityOpen = false;
private static boolean isSendChat = false;
private static App instanceApp;
private CountDownTimer countDownTimer;
private Handler handler = new Handler();
@Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
Timber.plant(new Timber.DebugTree());
instanceApp = this;
// TODO: Add this project to your fabric.io
/*Crashlytics crashlyticsKit = new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build();
Fabric.with(this, crashlyticsKit);*/
if (applicationComponent == null) {
applicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(App.get(this)))
.build();
}
}
public static App get(Context context){
return (App) context.getApplicationContext();
}
public ApplicationComponent getComponent(){
return applicationComponent;
}
public static boolean isChatActivityOpen() {
return isChatActivityOpen;
}
public static boolean isSendChat(){
return isSendChat;
}
public static synchronized App getInstance(){
return instanceApp;
}
public void setConnectivityListener(ConnectivityReceiver.ConnectivityReceiverListener listener){
ConnectivityReceiver.connectivityReceiverListener = listener;
}
public static void setChatActivityOpen(boolean isChatActivityOpen) {
App.isChatActivityOpen = isChatActivityOpen;
}
public static void setSendChatStatus(boolean isSendChat){
App.isSendChat = isSendChat;
}
public void startTimer(){
Intent intent = new Intent(getInstance().getApplicationContext(), SessionTimerService.class);
intent.setAction(Constant.ACTION_START_SERVICE);
startService(intent);
}
public void stopTimer(){
Intent intent = new Intent(getInstance().getApplicationContext(), SessionTimerService.class);
intent.setAction(Constant.ACTION_STOP_SERVICE);
stopService(intent);
}
@Override
public void onTerminate() {
super.onTerminate();
}
}
要在我的活动中启动计时器,请按以下步骤操作:
App.startTimer()
或App.stopTimer()
注意:我在一个活动中致电App.startTimer()
。
请帮助修复此错误。我谢谢你。
答案 0 :(得分:0)
如果您要定位的是Android 8+,则this is an intended behaviour
您的后台服务将在几分钟后被杀死。
如果您定位的版本早于8:
您应该在Application类的onCreate中使用startTimer。
如果您将服务置为粘性,则该服务一旦被终止,将重新启动Application上下文,并且仅执行Application类的onCreate内的内容。
如果将startTimer保留在Activity中,则它将按前台意图启动,一旦终止,它将不会重新创建自身。
答案 1 :(得分:0)
这取决于您要如何使用服务。
如果您希望在应用被终止时运行服务,这将会发生:
应用正在运行->被杀死->上下文被破坏->服务在被杀死时重新启动应用,从那里开始,只有应用上下文是有效的,因此,您的应用中唯一会发生的事情就是onCreate事件的发生应用类别。 一旦您杀死了您的应用程序,所有内容都会被销毁,然后它将尝试重新创建它的一部分。
因此,一旦您终止应用程序,它将不会重新创建活动,也不会重新创建服务。
因此,如果您希望某项服务在特定的活动中启动,那么一旦您终止了该应用程序,该服务将无法正常工作。
public class App extends Application {
private ApplicationComponent applicationComponent;
private static boolean isChatActivityOpen = false;
private static boolean isSendChat = false;
private static App instanceApp;
private CountDownTimer countDownTimer;
private Handler handler = new Handler();
@Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
Timber.plant(new Timber.DebugTree());
instanceApp = this;
startTimer();
// TODO: Add this project to your fabric.io
/*Crashlytics crashlyticsKit = new Crashlytics.Builder()
.core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
.build();
Fabric.with(this, crashlyticsKit);*/
if (applicationComponent == null) {
applicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(App.get(this)))
.build();
}
}
答案 2 :(得分:0)
您可以执行以下操作: