通过前面的学习,大家会发现我们在使用 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