Android Service - Service 引入(Service 概述、Service 类型、Service 初识、Service 简单任务、启动式服务、绑定式服务)

一、Service

  1. Service 是 Android 提供的后台组件,用于执行长时间运行的操作,不依赖用户界面(UI)

  2. Service 默认运行在主线程,耗时任务需手动管理线程

  3. Service 适用于无需用户交互的任务,例如,音乐播放、数据同步、位置跟踪等


二、Service 类型

1、启动式服务
  1. 通过 startService 方法启动

  2. 即使启动它的组件(例如,Activity、Fragment)被销毁,Service 仍可继续运行

  3. 任务完成后需手动调用 stopSelf 方法或 stopService 方法停止

2、绑定式服务
  1. 通过 bindService 方法绑定

  2. 多个组件(例如,Activity、Fragment)可绑定到同一个 Service

  3. 当所有绑定组件解绑时(调用 unbindService 方法),Service 自动销毁


三、Service 初识

1、Service
  • FirstService.java
package com.my.service.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class FirstService extends Service {
    
    

    public static final String TAG = FirstService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        Log.i(TAG, "onStartCommand");

        return super.onStartCommand(intent, flags, startId);
    }
}

2、AndroidManifest.xml
<service android:name=".myservice.FirstService" />
3、Activity Layout
  • activity_first_service_test.xml
<?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=".FirstServiceTestActivity">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • FirstServiceTestActivity.java
package com.my.service;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

import com.my.service.myservice.FirstService;

public class FirstServiceTestActivity extends AppCompatActivity {
    
    

    public static final String TAG = FirstServiceTestActivity.class.getSimpleName();

    private Button btnStartService;

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

        btnStartService = findViewById(R.id.btn_start_service);

        btnStartService.setOnClickListener(v -> {
    
    
            startService(new Intent(this, FirstService.class));
        });
    }
}
  • 输出结果
onStartCommand

四、Service 简单任务

1、Service
  • WorkService.java
package com.my.service.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class WorkService extends Service {
    
    

    public static final String TAG = WorkService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        new Thread(() -> {
    
    
            for (int i = 0; i < 5; i++) {
    
    
                try {
    
    
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }

                Log.i(TAG, i + "");
            }
        }).start();

        return super.onStartCommand(intent, flags, startId);
    }
}
2、AndroidManifest.xml
<service android:name=".myservice.WorkService" />
3、Activity Layout
  • activity_work_service_test.xml
<?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=".WorkServiceTestActivity">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • WorkServiceTestActivity.java
package com.my.service;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

import com.my.service.myservice.WorkService;

public class WorkServiceTestActivity extends AppCompatActivity {
    
    

    public static final String TAG = WorkServiceTestActivity.class.getSimpleName();

    private Button btnStartService;

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

        btnStartService = findViewById(R.id.btn_start_service);

        Intent intent = new Intent(this, WorkService.class);

        btnStartService.setOnClickListener(v -> {
    
    
            startService(intent);
        });
    }
}
  • 输出结果
0
1
2
3
4

五、启动式服务

1、Service
  • StartAndStopService.java
package com.my.service.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class StartAndStopService extends Service {
    
    

    public static final String TAG = StartAndStopService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        Log.i(TAG, "onStartCommand");

        Log.i(TAG, "任务开始执行");
        new Thread(() -> {
    
    
            try {
    
    
                Thread.sleep(3 * 1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("任务执行完毕");
        }).start();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
    
    
        super.onDestroy();

        Log.i(TAG, "onDestroy");
    }
}
2、AndroidManifest.xml
<service android:name=".myservice.StartAndStopService" />
3、Activity Layout
  • activity_start_and_stop_service_test.xml
<?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=".StartAndStopServiceTestActivity">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_start_service" />
</androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • StartAndStopServiceTestActivity.java
package com.my.service;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;

import com.my.service.myservice.StartAndStopService;

public class StartAndStopServiceTestActivity extends AppCompatActivity {
    
    

    public static final String TAG = StartAndStopServiceTestActivity.class.getSimpleName();

    private Button btnStartService;
    private Button btnStopService;

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

        btnStartService = findViewById(R.id.btn_start_service);
        btnStopService = findViewById(R.id.btn_stop_service);

        Intent intent = new Intent(this, StartAndStopService.class);

        btnStartService.setOnClickListener(v -> {
    
    
            startService(intent);
        });

        btnStopService.setOnClickListener(v -> {
    
    
            stopService(intent);
        });
    }
}
5、Test
  1. 点击【开启服务】按钮,输出结果
onStartCommand
任务开始执行
任务执行完毕
  1. 点击【停止服务】按钮,输出结果
onDestroy

六、绑定式服务

1、Service
  • BindAndUnbindService.java
package com.my.service.myservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

public class BindAndUnbindService extends Service {
    
    

    public static final String TAG = BindAndUnbindService.class.getSimpleName();

    private IBinder LocalBinder = new LocalBinder();

    public class LocalBinder extends Binder {
    
    
        public BindAndUnbindService getService() {
    
    
            return BindAndUnbindService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        Log.i(TAG, "onBind");

        return LocalBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
    
    
        Log.i(TAG, "onUnbind");

        return super.onUnbind(intent);
    }

    public void work() {
    
    
        Log.i(TAG, "任务开始执行");
        new Thread(() -> {
    
    
            try {
    
    
                Thread.sleep(3 * 1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("任务执行完毕");
        }).start();
    }
}
2、AndroidManifest.xml
<service android:name=".myservice.BindAndUnbindService" />
3、Activity Layout
  • activity_bind_and_unbind_service_test.xml
<?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=".BindAndUnbindServiceTestActivity">

    <Button
        android:id="@+id/btn_bind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="绑定服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_work"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="执行任务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_bind" />

    <Button
        android:id="@+id/btn_unbind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="解绑服务"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_work" />
</androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • BindAndUnbindServiceTestActivity.java
package com.my.service;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Button;

import com.my.service.myservice.BindAndUnbindService;

public class BindAndUnbindServiceTestActivity extends AppCompatActivity {
    
    

    public static final String TAG = BindAndUnbindServiceTestActivity.class.getSimpleName();

    private Button btnBind;
    private Button btnWork;
    private Button btnUnbind;

    private BindAndUnbindService bindAndUnbindService;

    private ServiceConnection serviceConnection = new ServiceConnection() {
    
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
    
    
            Log.i(TAG, "onServiceConnected");

            BindAndUnbindService.LocalBinder localBinder = (BindAndUnbindService.LocalBinder) service;
            bindAndUnbindService = localBinder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
    
    
            Log.i(TAG, "onServiceDisconnected");
        }
    };

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

        btnBind = findViewById(R.id.btn_bind);
        btnWork = findViewById(R.id.btn_work);
        btnUnbind = findViewById(R.id.btn_unbind);

        btnBind.setOnClickListener(v -> {
    
    
            bindService(new Intent(this, BindAndUnbindService.class), serviceConnection, Context.BIND_AUTO_CREATE);
        });

        btnWork.setOnClickListener(v -> {
    
    
            bindAndUnbindService.work();
        });

        btnUnbind.setOnClickListener(v -> {
    
    
            unbindService(serviceConnection);
        });
    }
}
5、Test
  1. 点击【开启服务】按钮,输出结果
onBind
onServiceConnected
  1. 点击【执行任务】按钮,输出结果
任务开始执行
任务执行完毕
  1. 点击【解绑服务】按钮,输出结果
onUnbind