IntetntService基本使用及源码解析

一、简介

    IntentService is a base class for {@link Service}s that handle asynchronous
 * requests (expressed as {@link Intent}s) on demand.  Clients send requests
 * through {@link android.content.Context#startService(Intent)} calls; the
 * service is started as needed, handles each Intent in turn using a worker
 * thread, and stops itself when it runs out of work.
  // IntentService用于处理异步请求,使用工作线程(子线程)处理每个intent,工作完后停止自己

 * <p>This "work queue processor" pattern is commonly used to offload tasks
 * from an application's main thread.  The IntentService class exists to
 * simplify this pattern and take care of the mechanics.  To use it, extend
 * IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService
 * will receive the Intents, launch a worker thread, and stop the service as
 * appropriate.
 // 使用时需要继承IntentService 实现onHandleIntent(Intent)方法,IntentService会接收到intents启动一个工作线程,并且会适当的停止服务

 * <p>All requests are handled on a single worker thread -- they may take as
 * long as necessary (and will not block the application's main loop), but
 * only one request will be processed at a time.
 // 所有的请求会在一个单独的工作线程处理,在不阻塞应用主循环的前提下会尽可能长存活,但是每次只处理一个请求

二、基本使用

1、创建类继承IntentService,并重写onHandleIntent()方法,重写无参构造方法

public class MyIntentService extends IntentService {
    private int progress = 0;

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        try {
        // 模拟耗时操作
            Thread.sleep(1000);
            while (true) {
                progress++;
                if (progress > 100) {
                    break;
                }
                sendBroadCast();
                Thread.sleep(100);

            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void sendBroadCast() {
        Intent mIntent = new Intent();
        mIntent.setAction("updateProgress");
        mIntent.putExtra("updateProgress", progress);
        getApplicationContext().sendBroadcast(mIntent);
    }
}

2、Activity中调用并更新UI

public class IntentServiceActivity extends Activity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);
        initBroadCastReceiver();
        initView();
    }

    private void initBroadCastReceiver() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("updateProgress");
        registerReceiver(broadcastReceiver, intentFilter);
    }


    private void initView() {
        Button btnStartService = findViewById(R.id.btn_start);
        btnStartService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(IntentServiceActivity.this, MyIntentService.class);
                startService(intent);
            }
        });

    }


    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == "updateProgress") {
                int progress = intent.getIntExtra("updateProgress", 0);
                ProgressBar progressBar = findViewById(R.id.progressBar);
                progressBar.setProgress(progress);

                if (progress == 100) {
                    Toast.makeText(IntentServiceActivity.this, "downLoadSuccess", Toast.LENGTH_SHORT).show();
                }
            }
        }
    };

}

3、layout文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start_service"/>

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="20dp"
        />

</android.support.v7.widget.LinearLayoutCompat>

4、效果图

这里写图片描述

三、源码分析

// 抽象类继承Service,为Service的子类
public abstract class IntentService extends Service 

构造方法

// 被子类构造调用
 /**
 * Creates an IntentService.  Invoked by your subclass's constructor.
 *
 * @param name Used to name the worker thread, important only for debugging.
 */
public IntentService(String name) {
 super();
mName = name;
    }

onCreate()

   @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        // 创建一个线程
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        // 获取线程的Looper
        mServiceLooper = thread.getLooper();
        // 使用当前线程looper创建线程
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

ServiceHandler

   private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            // 处理消息
            onHandleIntent((Intent)msg.obj);
            // 处理完后调用stopSelf,停止当前服务
            stopSelf(msg.arg1);
        }
    }

onStartCommand()

 @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        // 调用onStart方法
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

onStart()

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        // 通过mServiceHandler发送消息
        mServiceHandler.sendMessage(msg);
    }

onDestroy()

  @Override
    public void onDestroy() {
    // 生命周期结束直接将looper关闭,所以在该service使用完后会自动关闭
        mServiceLooper.quit();
    }

总结:
intentService通过创建子线程进行耗时操作,结合handler进行线程切换操作,所以可以进行耗时操作,在onDestroy()方法中,将当前工作线程的looper关闭,同时在handleMessage中通过stopSelf(msg.arg1);关闭service,完成生命周期绑定,处理完耗时操作无需自己处理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章