Android:服务在一段时间后被杀死并重新启动

时间:2017-04-22 08:48:51

标签: android service

我知道这是一个众所周知的主题,但我尝试过很多东西。我有一个专门针对特定用户的简单应用程序,应用程序有一个mainActivity,它在屏幕上显示一些状态,它启动两个服务,一个是从服务器发出请求(每5分钟一次),另一个是发送短信和重播服务器(每十分钟一次)。

该应用程序在Android 4.4.2的Samsung pocket 2上运行,此设备仅用于此应用程序。当设备连接到ADB时,服务工作正常,但如果我断开电话并让它正常运行,服务将被重复杀死并在一段时间后重新启动。消息被发送非常延迟。我会感谢任何建议。

这是我的代码:

主要活动:

public class MainActivity extends Activity {

private TextView _internet;
private TextView _signal;
private TextView _server;
private BroadcastReceiver receiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();

    IntentFilter intentFilter = new IntentFilter(Constants.SS);

    receiverWorker();
    registerReceiver(receiver, intentFilter);

    startService(new Intent(this, RefreshDBService.class));
    startService(new Intent(this, SmsService.class));


}

private void receiverWorker() {
    receiver  = new BroadcastReceiver() {

        public void onReceive(Context arg0, Intent arg1) {
            checkState();
        }};

}

public void refreshButonClicked(View v) {
    checkState();
}`

这是我的第一项服务:

public class RefreshDBService extends Service {

private Thread _backgroundWork;
private ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
private DataBaseOperations _dataSource;

@Override
public void onCreate() {
    super.onCreate();

    _dataSource = new DataBaseOperations(this);

    _backgroundWork = new Thread(new Runnable() {
        @Override
        public void run() {

            if(Checks.checkInternetConnection(getApplicationContext())){
                if(ServerOperations.isServerAvailable(getApplicationContext())){

                    String inputData = ServerOperations.makeRequest(Constants.GET_DATA_ROUTE, ServerOperations.getMessagesFromServer(getApplicationContext()));

                    ArrayList<DataSmsObj> dataFromServer=null;
            if(inputData!=null && !inputData.isEmpty()){
                dataFromServer = ServerOperations.fromJsonToObjects(inputData);

                if(dataFromServer.size()>0){
                    _dataSource.open();
                    _dataSource.insertDataFromServer(dataFromServer);
                    _dataSource.close();
                }
            }
            System.out.println("check server for messages in pending status,  received -> "+ dataFromServer.size());

        }else{
            System.out.println("no server");
            sentErrorToUI(Constants.NO_SERVER);
        }
    }else{
        System.out.println("no internet");
        sentErrorToUI(Constants.NO_INTERNET);
    }


}
    });
}


public int onStartCommand(Intent intent, int flags, int startId) {  
    scheduleTaskExecutor.scheduleWithFixedDelay(_backgroundWork, 0, Constants.NEXT_CYCLE/2, TimeUnit.MINUTES);
    return START_REDELIVER_INTENT;
}

@Override
public void onDestroy() {
    super.onDestroy();
    scheduleTaskExecutor.shutdownNow();
}

public IBinder onBind(Intent intent) {
    return null;
}

private void sentErrorToUI(String message){
    Intent intent = new Intent(Constants.SS);
    intent.putExtra(Constants.SS, message);
    System.out.println("trimit" +message);
    sendBroadcast(intent);
}

}

这是第二个:

public class SmsService extends Service {

private Thread _backgroundWork;
private ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);

private DataBaseOperations _dataSource;

@Override
public void onCreate() {
    super.onCreate();
    _dataSource = new DataBaseOperations(this);

    _backgroundWork = new Thread(new Runnable() {
        @Override
        public void run() {

            sendFeedbackToServer();             

            List<DataSmsObj> dataToSent =  new ArrayList<DataSmsObj>();
            _dataSource.open();
                dataToSent = _dataSource.getDataToSent();
            _dataSource.close();

            System.out.println("messages to sent: "+ dataToSent.size());
            for (int i = 0; i < dataToSent.size(); i++) {

                //here the messages are send, the code is to long to put it here, but if is need i can do it afterwards 

            }   
        }
    });
}

public int onStartCommand(Intent intent, int flags, int startId) {  
    scheduleTaskExecutor.scheduleWithFixedDelay(_backgroundWork, 0, Constants.NEXT_CYCLE, TimeUnit.MINUTES);
    return START_REDELIVER_INTENT;
}

@Override
public void onDestroy() {
    super.onDestroy();
    scheduleTaskExecutor.shutdownNow();

public IBinder onBind(Intent intent) {
    return null;
}

3 个答案:

答案 0 :(得分:0)

如果从计算机上拔下设备,您的设备将会休眠。所以,解决方案: 使用startForeground方法来防止服务被杀死和/或使用AlarmManager来为事件充电。

可以使用start_stiky标志,但只有在被系统杀死时才会重新启动进程。

答案 1 :(得分:0)

答案 2 :(得分:0)

如果您将后台Service与计划任务一起使用,则可能会被系统杀死。防止查杀的唯一方法是前景Service。引用文档:

  

前台服务是用户主动了解的服务,并且不是内存不足时系统可以杀死的服务。

您必须使用startForeground()Service内调用Notification方法来展示它。有关详细信息,请查看:https://developer.android.com/guide/components/services.html#Foreground

顺便说一下,我建议你使用api 21上面的新JobScheduler api。 https://developer.android.com/reference/android/app/job/JobScheduler.html