通过前面的学习,大家会发现我们在使用 Service 时总会创建一个线程来执行任务,而不是直接在 Service中执行。这是因为 Service 中的程序仍然运行于主线程中,当执行一项耗时操作时,不新建一个线程的话很容易导致 Application Not Responding 错误。当需要与 UI线程进行交互时,使用 Handler 机制来进行处理。
为了简化操作,Android提供了IntentService类。IntentService是 Android中提供的后台服务类,是Service 自动实现多线程的子类。IntentService 在 onCreate(函数中通过 HandlerThread 单独开启一个线程来处理所有Intent 请求对象所对应的任务,这样以免请求处理阻塞主线程。执行完一个 Intent 请求对象所对应的工作之后,如果没有新的 Intent 请求到达,就自动停止Service;否则执行下一个Intent 请求所对应的任务,直至最后执行完队列的所有命令,服务也随即停止并被销毁。所以如果使用 IntentService,用户并不需要主动使用 stopService()或者在lntentService 中使用 stopSelf()来停止。
lntentService在处理请求时采用的也是 Handler机制,它通过创建一个名叫 ServiceHandler 的内部 Handler 直接绑定到 HandlerThread所对应的子线程。ServiceHandler 把处理一个 intent 所对应的请求都封装到 onHandleIntent()方法中,在开发时只需要直接重写 onHandleIntent()方法,当开启服务之后系统会自动调用此方法来处理请求。
使用 IntentService 相当简单,只需继承 IntentService类,实现 onHandleIntent()方法并在其中处理相关请求的操作即可。下面通过一个实例来说明。
创建一个 Activity 类,并在布局文件中加入一个 Button 来开启服务。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="start" android:text="启动IntentService" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.089" /></androidx.constraintlayout.widget.ConstraintLayout>复制代码在MainActivity中捕获Button按钮的点击事件,开启服务,代码如下:
package com.example.test47;
import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void start(View view){ Intent intent=new Intent(MainActivity.this,MyService.class); startService(intent);//启动service }}复制代码
最后创建一个类继承IntentService,代码如下:
package com.example.test47;
import android.app.IntentService;import android.content.Intent;import android.util.Log;import androidx.annotation.Nullable;//定义IntentService类public class MyService extends IntentService { int i = 3;//构造方法 public MyService() { super(""); } //耗时任务 @Override protected void onHandleIntent(@Nullable Intent intent) { while (i > 0) { Log.i("=====", i + ""); i--; try { Thread.sleep(100);//隔100ms打印数字i } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public void onCreate() { super.onCreate(); Log.i("======", "onCreate"); } @Override public void onDestroy() { Log.i("======", "onDestroy"); }}//TODO 特别注意构造方法,不然程序会出错复制代码
在AndroidManifest.xml文件中注册此服务:
<service android:name=".MyService"></service>
复制代码运行程序,点击按钮,观察Log会发现,确实如前文所说,当Intent请求的操作完成之后Service会自动销毁。Log如下:
实例很简单、很容易理解,通过这个实例可以很容易地学会如何使用IntentService。当然如果想要进一步了解IntentService的运行机制,也可以阅读IntentService类的源码。
android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。
yzw92 2021-11-26 06:43