【问题标题】:Android kill service when app relauch and close?应用程序重新启动和关闭时Android终止服务?
【发布时间】:2015-06-26 07:06:48
【问题描述】:

当达到预定时间时,我必须在后台运行一项任务。我将唤醒我的服务的任务分配给Alarm Manager,如果应用程序是后台/正在运行,它会很好。服务在应用程序的后台保持正常运行如果在开始服务后没有改变应用程序的状态,以及前景状态。为了更好地理解下面给出的场景。

案例 1:

1.设置时间表并将时间发送给警报管理器并保持应用程序运行。

2.报警管理器在时间到时调用服务。

3.服务开始运行

4.当我关闭我的应用服务时会停止

案例 2:

1.设置时间表并将时间发送到警报管理器并在后台关闭 app.now 应用程序。

2.报警管理器在时间到时调用服务。

3.服务开始运行

4.重新启动 app.service 继续运行/正常工作。

5.现在关闭应用,结果是service dead。

我只能通过 Alarm Manager 调用该服务,而不是每次应用程序为此目的在服务 onStartCommand 中启动时,我返回 START_NOT_STICKY 并且我不想使用 START_STICKY。如果我转到START_STICKY,它不会考虑预定时间。问题是我不想再次检查时间,因为Alarm Manager 做得很好。

当应用程序在低内存上运行时,服务会被破坏。解决方案是使用 startForeground 而不是 startService 吗?

如何让我的服务稳定运行而不用担心应用程序的打开/关闭状态?

设定时间表

public void setAction(View v) {
        Calendar calendar = Calendar.getInstance();
        int hour = Integer.parseInt(HH.getText().toString());
        int minute = Integer.parseInt(MM.getText().toString());
        int second = Integer.parseInt(SS.getText().toString());
        String peried = PP.getText().toString();
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.AM_PM, peried.equalsIgnoreCase("AM") ? Calendar.AM : Calendar.PM);
        Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
        myIntent.putExtra(ACTION,
                ACTION_SC_1);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, REQUEST_CODE_SC_1, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
    }

服务类

public class MyService extends Service {
   

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            final String action = intent.getStringExtra(ACTION);
            final Handler handler = new Handler();
            final Timer timer = new Timer();
            final TimerTask doAsynchronousTask = new TimerTask() {
                @Override
                public void run() {
                    handler.post(new Runnable() {
                        public void run() {
                            try {
                                Toast.makeText(MyAlarmService.this, "Running....", Toast.LENGTH_LONG).show();

                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                            }
                        }
                    });
                }
            };
            timer.schedule(doAsynchronousTask, 1000, 5000); //execute in every 5000 msdo

          //  this.stopSelf();
        } catch (Exception e) {
           //TODO
        }

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Toast.makeText(this, "Killed", Toast.LENGTH_LONG).show();
    }


 

【问题讨论】:

  • 您在活动中的任何位置调用 stopService() 方法?
  • 从来没有,我检查过可能的情况:)
  • START_STICKY 将立即重启被操作系统停止的服务,START_REDELIVER_INTENT 将减慢重启操作:)

标签: android service kill


【解决方案1】:

有很多方法可以避免杀死服务...但我们不能保证。在内存不足的情况下,服务将被操作系统杀死。在这种情况下,如果您返回START_STICKY,这将以空意图重新启动服务。如果您希望意图不为空,请返回 START_REDELIVER_INTENT 查看安卓文档here

【讨论】:

  • 因为这将创建我们应用程序的新副本。这是一种有效的方式吗?
  • 服务将在单独的进程中运行...是的,这是避免杀死服务的推荐方法。
  • 内存使用情况如何?
  • 在单独的进程中运行不会影响内存使用。
  • 但我认为像 facebook 这样流行的应用程序只在主进程中运行他们的服务。它怎么可能?
猜你喜欢
  • 1970-01-01
  • 2014-10-12
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多