有没有办法确保服务在启动后继续在后台运行,即使用户从最近屏幕清除应用程序?一个完美的例子是 Pandora 的应用程序,一旦它开始播放,即使你从最近删除它,音乐继续播放并且通知仍然存在。
在我的示例应用程序中,我有一个简单的处理程序,它只记录 500 毫秒的当前时间,以便我可以查看服务是否正在运行,然后我使用 4 个切换之一启动它,每个设置都使其从 4 个服务之一启动启动类型(START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY)。我启动服务,退出应用程序,然后从最近删除它。在每种情况下,服务都会终止并且循环日志记录会停止。
MainActivity.java
public class MainActivity extends Activity {
    private Boolean recording = false;
    private Intent recordingService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recordingService = new Intent(this, RecordingService.class);
        Button START_STICKY = (Button) findViewById(R.id.START_STICKY);
        START_STICKY.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View arg0) {
                startStopRecordingService(Service.START_STICKY);
            }
        });
        Button START_NOT_STICKY = (Button) findViewById(R.id.START_NOT_STICKY);
        START_NOT_STICKY.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View arg0) {
                startStopRecordingService(Service.START_NOT_STICKY);
            }
        });
        Button START_REDELIVER_INTENT = (Button) findViewById(R.id.START_REDELIVER_INTENT);
        START_REDELIVER_INTENT.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View arg0) {
                startStopRecordingService(Service.START_REDELIVER_INTENT);
            }
        });
        Button START_STICKY_COMPATIBILITY = (Button) findViewById(R.id.START_STICKY_COMPATIBILITY);
        START_STICKY_COMPATIBILITY.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View arg0) {
                startStopRecordingService(Service.START_STICKY_COMPATIBILITY);
            }
        });
    }
    private void startStopRecordingService(int START_TYPE) {
        if (recording) {
            recordingService.removeExtra(RecordingService.START_TYPE);
            stopService(recordingService);
        } else {
            recordingService.putExtra(RecordingService.START_TYPE, START_TYPE);
            startService(recordingService);
        }
        recording = !recording;
    }
}
录音服务.java
public class RecordingService extends Service
{
    public final static String START_TYPE = "START_TYPE";
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startID) {
        Log.i(getClass().getName(), "onStartCommand");
        int start_type = intent.getExtras().getInt(START_TYPE);
        Log.i(getClass().getName(), "START_STICKY: " + String.valueOf(start_type == Service.START_STICKY));
        Log.i(getClass().getName(), "START_NOT_STICKY: " + String.valueOf(start_type == Service.START_NOT_STICKY));
        Log.i(getClass().getName(), "START_REDELIVER_INTENT: " + String.valueOf(start_type == Service.START_REDELIVER_INTENT));
        Log.i(getClass().getName(), "START_STICKY_COMPATIBILITY: " + String.valueOf(start_type == Service.START_STICKY_COMPATIBILITY));
        logTime();
        return start_type;
    }
    @Override
    public void onDestroy() {
        Log.i(getClass().getName(), "onDestroy");
        updateDisplayTimer.removeCallbacks(updateDisplayHandler);
    }
    public void logTime() {
        Log.i(getClass().getName(), String.valueOf(System.currentTimeMillis()));
        updateDisplayTimer.postDelayed(updateDisplayHandler, LOOP_TIME);
    }
    private static final int LOOP_TIME = 500;
    private Handler updateDisplayTimer = new Handler();
    private Runnable updateDisplayHandler = new Runnable() {
        @Override
        public void run() {
            logTime();
        }
    };
}