后台服务在android中被杀死

Ash*_*win 36 android android-service

我们开发了一个Android应用程序,它涉及后台服务.为了实现我们使用的后台服务IntentService.我们希望应用程序每次轮询服务器60 seconds.所以在这里IntentService,服务器在while循环中被轮询.在while循环结束时,我们使用了Thread.sleep(60000)以便下一次迭代仅在60秒后开始.
但是在Logcat我看来,有时需要应用程序唤醒超过5分钟(从睡眠中退出并开始下一次迭代).它永远不会1 minute像我们想要的那样.

这是什么原因?后台服务应该以不同的方式实施吗?

Problem2

Android会在一段时间后终止此​​后台进程(意向服务).不能确切地说什么时候.但有时在后台服务被杀之前的几小时甚至几天.如果你能告诉我这个的原因,我将不胜感激.因为服务并不意味着被杀死.只要我们想要它们,它们就意味着在后台运行.

代码:

@Override
 protected void onHandleIntent(Intent intent) {
  boolean temp=true;
  while(temp==true) {
    try {
      //connect to the server 
      //get the data and store it in the sqlite data base
    }
    catch(Exception e) {
      Log.v("Exception", "in while loop : "+e.toString());
    }
    //Sleep for 60 seconds
    Log.v("Sleeping", "Sleeping");
    Thread.sleep(60000);
    Log.v("Woke up", "Woke up");

    //After this a value is extracted from a table
    final Cursor cur=db.query("run_in_bg", null, null, null, null, null, null);
    cur.moveToLast();
    String present_value=cur.getString(0);
    if(present_value==null) {
       //Do nothing, let the while loop continue  
    }
    else if( present_value.equals("false") || present_value.equals("False") ) {
       //break out of the while loop
       db.close();
       temp=false;
       Log.v("run_in_bg", "false");
       Log.v("run_in_bg", "exiting while loop");
       break;
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

但是每当服务被杀死时,它就会在进程处于睡眠状态时发生.最后一个日志读取 - Sleeping : Sleeping.为什么服务被杀?

Ale*_*exN 78

主要问题是我们不能说

服务并不意味着被杀死.只要我们想要它们,它们就意味着在后台运行.

基本上,这不是真的.系统仍然可以在低内存和其他情况下终止服务.有两种方法可以解决这个问题:

  1. 如果要实现该服务,请覆盖onStartCommand()并返回 START_STICKY结果.它会告诉系统即使它因内存不足而想要终止服务,只要内存恢复正常就应该重新创建它.
  2. 如果你不确定第一种方法是否有效 - 你将不得不使用AlarmManager http://developer.android.com/reference/android/app/AlarmManager.html.这是一个系统服务,它会在您告诉时执行操作,例如定期执行.这将确保如果您的服务将被终止,或者甚至整个过程将死亡(例如强制关闭) - 它将由AlarmManager 100%重新启动.

祝好运

  • 请检查此方法 - http://developer.android.com/reference/android/app/Service.html#startForeground如上所述,运行主要用户功能(如音乐播放)的繁重服务可以startForeground() - 系统将尽量不要阻止它.但是您需要提供通知以向用户显示后台服务正在运行.此外,仍然无法保证系统不会阻止它,但它的可能性要小得多. (13认同)
  • 如果我没记错,任何进程都被强制关闭AlarmManager不会再启动它. (7认同)
  • 如果情况并非总是如此,那么音乐播放器,雅虎邮箱,脸书等的背景服务呢.他们永远不会被杀死. (6认同)

Ale*_*tin 6

您可以使用专门为此目的而设计的ScheduledExecutorService.

不要使用Timers,如"Java Concurrency in Practice"中所示,它们可能非常不准确.


zap*_*apl 5

IntentService不打算继续在while循环中运行.我们的想法是对a做出反应Intent,做一些处理并在完成后停止服务.

这并不意味着它不起作用,我不能告诉你为什么你看到这么长的延迟,但更清洁的解决方案是使用一些外部来源定期戳服务.除了vanilla Java方法,您还可以查看文档中提到的AlarmManager或者.HandlerAlarmManager

这样的Handler方式会起作用

public class TriggerActivity extends Activity implements Handler.Callback {
    // repeat task every 60 seconds
    private static final long REPEAT_TIME = 60 * 1000;
    // define a message id
    private static final int MSG_REPEAT = 42;

    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHandler = new Handler(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // start cycle immediately
        mHandler.sendEmptyMessage(MSG_REPEAT);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // stop cycle
        mHandler.removeMessages(MSG_REPEAT);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler = null;
    }

    @Override
    public boolean handleMessage(Message msg) {
        // enqueue next cycle
        mHandler.sendEmptyMessageDelayed(MSG_REPEAT, REPEAT_TIME);
        // then trigger something
        triggerAction();
        return true;
    }

    private void triggerAction() {
        // trigger the service
        Intent serviceIntent = new Intent(this, MyService.class);
        serviceIntent.setAction("com.test.intent.OPTIONAL_ACTION");
        startService(serviceIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

一个简单的Activity(可以扩展为在所有活动中都具有该功能),Message它在运行时始终发送自己(在此之间onStart和之间onStop)