• IntentService和HandlerThread的使用以及源码阅读


    使用
    MyIntentService.java

    public class MyIntentService extends IntentService {


    /**
    * 是否正在运行
    */
    private boolean isRunning;

    /**
    *进度
    */
    private int count;

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

    /**
    * Creates an IntentService. Invoked by your subclass's constructor.
    *
    * @param name Used to name the worker thread, important only for debugging.
    */
    public MyIntentService(String name) {
    super(name);
    }


    @Override
    protected void onHandleIntent(Intent intent) {
    Logout.e("onHandleIntent"+intent.getStringExtra("name"));
    try {
    Thread.sleep(1000);
    isRunning = true;
    count = 0;
    while (isRunning) {
    count++;
    if (count >= 100) {
    isRunning = false;
    }
    Thread.sleep(50);
    Logout.e("线程运行中..."+ count);
    }

    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    Logout.e("结束了任务");
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    Logout.e("线程结束运行..." + count);
    }

    public static class Logout{
    private static final String TAG = "Logout";
    public static void e(String conent){
    Log.d(TAG, "e: "+conent);
    }
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    public classTestActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_async_task);

    startService(new Intent(this, MyIntentService.class));
    new Handler().post(new Runnable() {
    @Override
    public void run() {
    //延迟一段时间,发送第二次消息
    Intent intent = new Intent(AsyncTaskActivity.this, MyIntentService.class);
    intent.putExtra("name", "helloWorld");
    startService(intent);
    }
    });
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    // handlerThread.quit();
    // unbindService(serviceConnection);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    上面就是简单的使用IntentService的教程。 IntentService是一个抽象类,所以需要自己集成实现,这里有两点需要注意。

    自己实现的类需要提供无参的构造函数
    IntentService 是在onHandleIntent中处理耗时操作,这里的intent 就是startService中的intent.
    源码分析
    我们首先来看一下IntentService 的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();
    //构造一个IntentService,并启动
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    //使用HandlerThread 的looper 构造一个handler,这样就可以从HandlerThread接收发送消息
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    HandlerThread中比较值得关注的就是run方法。

    @Override
    public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
    mLooper = Looper.myLooper();
    notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    这里的代码也比较简单,流程基本上就是在非ui thread中构建Handler的标准流程,然后会走到 Looper.loop();中进入死循环。所以HandlerThread在使用结束以后,需要记得调用quit方法,停止死循环。

    关注完oncreate方法,我们来着重观察一下IntentServcie的onstart 和 onStartCommand方法

    @Override
    public void onStart(Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
    }

    /**
    * You should not override this method for your IntentService. Instead,
    * override {@link #onHandleIntent}, which the system calls when the IntentService
    * receives a start request.
    * @see android.app.Service#onStartCommand
    */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    可以看到这里利用了onStartCommand 每次startService每次都会调用onStartCommand的特点,用来给IntentService传递消息。IntentService收到消息后,就会调用mServiceHandler 将消息发送出去。这里主要的作用是将主线程的信息传递到HandlerThread。所以接下来,我们来看下ServiceHandler的具体的实现。

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

    @Override
    public void handleMessage(Message msg) {
    onHandleIntent((Intent)msg.obj);
    stopSelf(msg.arg1);
    }
    }
    --------------------- 

  • 相关阅读:
    SSH 远程执行任务
    C# 创建压缩文件
    迁移 SQL Server 到 Azure SQL 实战
    在 Azure 上部署 Asp.NET Core Web App
    linux kill 命令
    VS 远程调试 Azure Web App
    Azure 基础:自定义 Table storage 查询条件
    NSOperation的使用细节 [2]
    NSOperation的使用细节 [1]
    [翻译] SSKeychain
  • 原文地址:https://www.cnblogs.com/ly570/p/11021251.html
Copyright © 2020-2023  润新知