IntentService 소개 및 소스 코드 분석

소개

IntentService 는 Service에서 상속된 추상 클래스이며 여전히 본질적으로 Service이므로 사용할 하위 클래스를 만들어야 합니다. IntentService는 또한 HandlerThread를 구현 하고 시간이 많이 걸리는 작업을 처리하는 데 특별히 사용되는 WorkerThread 스레드를 내부적으로 유지 관리합니다. 실제로 IntentService 의 모든 작업은 이 WorkerThread 에서 수행 됩니다.
동일한 IntentService가 여러 번 시작되면 매번 시작된 시간이 많이 걸리는 작업은 WorkerThread에서 메시지 대기열 형태로 순차적으로 실행되고 작업 실행은 onHandleIntent() 메서드에서 완료됩니다. 실행이 완료되면 stopSelf()가 호출되어 자동으로 종료되므로 수동으로 종료할 필요가 없습니다 .

이점

1. 우선 순위가 상대적으로 높고 사망 확률이 낮습니다.
본질적으로 IntentService 도 하위 스레드를 열지만  IntentService는 Service 에서 상속되므로 Android 시스템의 Kill App 메커니즘에 따라  IntentService를 사용하는 애플리케이션이 더 높은 우선순위를 갖습니다. 평신도의 관점에서 IntentService를 백그라운드 작업으로 사용하면 프로그램이 백그라운드로 후퇴할 때 종료될 가능성이 낮아집니다.
2. stopSelf() 메서드를 자동으로 호출하여 종료합니다.
IntentService는 작업 실행이 완료된 후 종료되며 stopService()에 대한 외부 호출이 필요하지 않습니다.

결점

IntentService는 HandlerThread를 유지하기 때문에 그 안의 비동기 작업은 대기열에 저장되므로 단일 스레드-다중 작업-동기 실행만 달성할 수 있으며 이는 다중 스레드 동시성을 달성하려는 비즈니스 요구에 적합하지 않습니다. 

특징

1. 모든 Intent 요청을 처리하기 위해 내부적으로 독립 스레드 WorkerThread를 생성합니다.
2. 멀티스레딩에 대한 걱정 없이 onHandleIntent()에서 시간 소모적인 로직을 처리하기 위해 독립적인 스레드 WorkerThread가 내부적으로 생성됩니다.
3. 시간 소모적인 모든 작업이 완료된 후 IntentService는 stopSelf()를 호출하여 자동으로 중지합니다.
4. bindService()를 사용하여 IntentService를 바인딩할 수 없습니다 .
5. onBInd() 메서드는 null을 반환하므로 신경 쓸 필요가 없습니다.
6. onStartCommand()는 요청된 Intent 작업을 대기열에 추가하는 기본 구현을 제공합니다 .

사용하는 방법

IntentService는 단일 사례와 유사합니다. 동일한 IntentService 클래스가 여러 번 시작되고 onCreate()가 한 번만 실행되며,
onStart / onStartCommand의 실행 횟수 = 시작 횟수, onHandleIntent() 메서드는 대기열의 의도 작업을 차례로 실행합니다.
public class MyService extends IntentService {
    //这里必须有一个空参数的构造实现父类的构造,否则会报异常
    //java.lang.InstantiationException: 
    //java.lang.Class<***.MyService> has no zero argument constructor
    public MyService() {
        super("");
    }
    
    @Override
    public void onCreate() {
        System.out.println("onCreate");
        super.onCreate();
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        System.out.println("onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        System.out.println("onStart");
        super.onStart(intent, startId);
    }

    @Override
    public void onDestroy() {
        System.out.println("onDestroy");
        super.onDestroy();
    }

    //这个是IntentService的核心方法,它是通过串行来处理任务的,也就是同步处理
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        System.out.println("工作线程是: "+Thread.currentThread().getName());
        String task = intent.getStringExtra("task");
        System.out.println("任务是 :"+task);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MyService.class);
        intent.putExtra("task","播放音乐");
        startService(intent);
        intent.putExtra("task","播放视频");
        startService(intent);
        intent.putExtra("task","播放图片");
        startService(intent);
    }
}

소스 코드 분석   

// IntentService 的 onCreate() 方法,内部启动了一个 HandlerThread 线程。
@Override
public void onCreate() {
   super.onCreate();
   //HandlerThread 就是一个带有 handler 的 thread ,这里就是创建了一个线程,
   //注意这个线程的名字上面的日志打印中"工作线程是: IntentService[]"
   //因为我们在自定义的MyService里面,构造方法写的是super(""),如果写的不是空串,
   //上面的日志打印就应该是"工作线程是: IntentService[我们定义的名称]"
   HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
   thread.start();
   //获取这个线程的looper
   mServiceLooper = thread.getLooper();
   //创建了一个handler
   mServiceHandler = new ServiceHandler(mServiceLooper);
}
//我们来看一下 ServiceHandler 对消息的处理
private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }
    @Override
    public void handleMessage(Message msg) {
        //处理逻辑是我们在MyService里面重写的这个方法
        onHandleIntent((Intent)msg.obj);
        //从这里可以看出,我们执行完任务后,service就销毁了
        stopSelf(msg.arg1);
    }
}
// 在onStart() 方法里发出了消息。
@Override
public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

지침

1. bindService를 통해 IntentService를 시작할 수 없는 이유는 무엇입니까?
bindService가 시작되면 onStartCommand() 메서드가 실행되지 않고 OnHandleIntent()가 호출되지 않기 때문에 일반 Service와 다를 바 없습니다.
2. IntentService가 여러 번 시작될 때 이벤트가 순차적으로 실행되는 이유는 무엇입니까?
IntentService에서 사용되는 Handler, Looper 및 MessageQueue 메커니즘은 실행을 위해 스레드에 메시지를 보냅니다.
따라서 IntentService를 여러 번 시작하면 새 서비스와 새 스레드가 다시 생성되지 않고 실행을 위해 메시지 큐에 메시지가 추가됩니다.
3. 서비스 종료 후 후속 이벤트를 진행할 수 없나요?
서비스가 중지되면 Looper.quit() 메서드가 호출되어 메시지 대기열의 메시지를 지우고 후속 이벤트는 실행되지 않습니다.
@Override
public void onDestroy() {
    mServiceLooper.quit();
}

Supongo que te gusta

Origin blog.csdn.net/m0_49508485/article/details/127255191
Recomendado
Clasificación