Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách triển khai START_STICKY cho Service Android

Hiểu về START_STICKY

START_STICKY là flag trả về trong onStartCommand() chỉ định hành vi khi Service bị hệ thống kill do thiếu bộ nhớ:

  • START_STICKY: Hệ thống sẽ restart Service sau khi có đủ bộ nhớ, gọi onStartCommand() với intent = null
  • START_NOT_STICKY: Không restart tự động
  • START_REDELIVER_INTENT: Restart và redeliver intent cuối cùng

Ví dụ triển khai

Bước 1-2: Dự án và Layout

Giống các bài trước: Empty Activity + TextView làm nút Start/Stop.

Bước 3: MainActivity.java

package com.example.andy.myapplication;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView text = findViewById(R.id.text);

        text.setOnClickListener(v -> {
            if (isMyServiceRunning(StickyService.class)) {
                text.setText("Stopped");
                stopService(new Intent(this, StickyService.class));
            } else {
                text.setText("Started");
                startService(new Intent(this, StickyService.class));
            }
        });
    }

    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}

Bước 4: StickyService.java

package com.example.andy.myapplication;

import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.RequiresApi;
import android.widget.Toast;

public class StickyService extends Service {

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

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("StickyService", "onCreate called");
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Sticky Service started", Toast.LENGTH_LONG).show();
        Log.d("StickyService", "onStartCommand - START_STICKY");
        
        // Giả lập công việc nền
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(1000);
                    Log.d("StickyService", "Working... " + i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        return START_STICKY; // Quan trọng: yêu cầu restart nếu bị kill
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Sticky Service destroyed", Toast.LENGTH_LONG).show();
        Log.d("StickyService", "onDestroy called");
    }
}

Bước 5: Manifest

<service android:name=".StickyService" />

Kiểm tra START_STICKY hoạt động

  1. Chạy app, bật Service
  2. Mở Settings → Apps → Your App → Force Stop (hoặc kill process từ Developer Options)
  3. Quan sát logcat: Service sẽ tự restart sau vài giây, onCreate() và onStartCommand(null, ...) được gọi lại
Lưu ý thực tế: Từ Android 8.0, Background Service bị giới hạn. START_STICKY chỉ hoạt động tốt cho Foreground Service. Để đảm bảo service chạy liên tục, hãy kết hợp với startForeground() (xem bài trước).