安卓基础之《(28)—Service组件》

一、Service概述

1、Service是什么

Service是一个应用组件,它用来在后台完成一个时间跨度比较大的工作且没有关联任何界面

2、应用退出,Service还在运行

3、一个Service可以完成:访问网络、播放音乐、文件IO操作、大数据量的数据库操作

4、Service的特点

(1)Service在后台运行,不用与用户进行交互

(2)即使应用退出,服务也不会停止

(3)启动应用会创建一个进程,应用退出,但是进程没死

(4)在默认情况下,Service运行在应用程序进程的主线程(UI线程)中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在子线程中处理,避免阻塞用户界面

二、Service的分类

1、Local Service(本地服务)

Service对象与Service的启动者在同个进程中运行,两者的通信是进程内通信

2、Remote Service(远程服务)

Service对象与Service的启动者不在同一个进程中运行,这时存在一个进程间通信的问题,android专门为此设计了AIDL来实现进程间通信

三、本地Service

1、声明Service

在清单文件AndroidManifest.xml中静态声明‌

2、启动与停止Service

方式一:一般启动

startService(Intent intent)

stopService(Intent intent)

方式二:绑定启动

bindService(Intent intent, ServiceConnection connection)

unbindService(ServiceConnection connection)

3、只有当onBind()、onUnBind()方法执行了,才会执行ServiceConnection里的方法

当服务连接时,如果绑定的服务onBind()没有返回值,则不执行onServiceConnected()方法

4、例子

LocalServiceActivity.java

java 复制代码
package com.example.chapter10;

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.view.View;
import android.widget.Button;

import com.example.chapter10.service.LocalService;

public class LocalServiceActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_start;
    private Button btn_stop;
    private Button btn_bind;
    private Button btn_unbind;
    private ServiceConnection conn;

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

        findViewById(R.id.btn_start).setOnClickListener(this);
        findViewById(R.id.btn_stop).setOnClickListener(this);
        findViewById(R.id.btn_bind).setOnClickListener(this);
        findViewById(R.id.btn_unbind).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.btn_start) {
            startMyService(view);
        } else if (view.getId() == R.id.btn_stop) {
            stopMyService(view);
        } else if (view.getId() == R.id.btn_bind) {
            bindMyService(view);
        } else if (view.getId() == R.id.btn_unbind) {
            unbindMyService(view);
        }
    }

    // 启动服务
    public void startMyService(View v) {
        // 用显式意图,传入要启动的服务类
        Intent intent = new Intent(this, LocalService.class);
        startService(intent);
        Log.d("sam", "startMyService 启动服务");
    }

    // 停止服务
    public void stopMyService(View v) {
        Intent intent = new Intent(this, LocalService.class);
        stopService(intent);
        Log.d("sam", "stopMyService 停止服务");
    }

    // 绑定服务
    public void bindMyService(View v) {
        Intent intent = new Intent(this, LocalService.class);

        if (conn == null) {
            // 创建连接对象
            conn = new ServiceConnection() {

                @Override
                public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                    // 当activity和service连接上时,调用这个方法
                    Log.d("sam", "onServiceConnected 服务连接");
                }

                @Override
                public void onServiceDisconnected(ComponentName componentName) {
                    Log.d("sam", "onServiceDisconnected 服务断开连接");
                }
            };

            // 绑定service
            bindService(intent, conn, Context.BIND_AUTO_CREATE);

        } else {
            Log.d("sam", "已经绑定");
        }
    }

    // 解绑服务
    public void unbindMyService(View v) {
        if (conn != null) {
            // 解绑service
            unbindService(conn);
            conn = null;
        } else {
            Log.d("sam", "还没有绑定");
        }

    }
}

布局文件,activity_local_service.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".LocalServiceActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="测试启动本地服务"
        android:textSize="17sp"
        android:gravity="center"/>
    <Button
        android:id="@+id/btn_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="启动服务"/>
    <Button
        android:id="@+id/btn_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="停止服务"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="测试绑定本地服务"
        android:textSize="17sp"
        android:gravity="center"/>
    <Button
        android:id="@+id/btn_bind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="绑定服务"/>
    <Button
        android:id="@+id/btn_unbind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解绑服务"/>
</LinearLayout>

清单文件

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication">

        <activity
            android:name=".LocalServiceActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".service.LocalService"
            android:enabled="true"
            android:exported="false" />
    </application>

</manifest>

自定义本地服务,LocalService.java

java 复制代码
package com.example.chapter10.service;

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 LocalService extends Service {

    public LocalService() {
        Log.d("sam", "LocalService()");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("sam", "LocalService onBind()");
        // 返回自定义Binder实例
        return new BasisBind();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d("sam", "LocalService onUnbind()");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("sam", "LocalService onCreate()");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("sam", "LocalService onDestroy()");
    }

    public class BasisBind extends Binder {

    }
}

5、日志

绑定/解绑

bash 复制代码
2026-04-13 17:17:10.517 13398-13398 sam                     com.example.chapter10                D  LocalService()
2026-04-13 17:17:10.523 13398-13398 sam                     com.example.chapter10                D  LocalService onCreate()
2026-04-13 17:17:10.526 13398-13398 sam                     com.example.chapter10                D  LocalService onBind()
2026-04-13 17:17:10.536 13398-13398 sam                     com.example.chapter10                D  onServiceConnected 服务连接
2026-04-13 17:17:14.453 13398-13398 sam                     com.example.chapter10                D  LocalService onUnbind()
2026-04-13 17:17:14.454 13398-13398 sam                     com.example.chapter10                D  LocalService onDestroy()

onServiceDisconnected仅在服务因异常情况被系统终止时触发‌,而不是在正常解绑服务时调用

相关推荐
lhbian4 小时前
PHP、C++和C语言对比:哪个更适合你?
android·数据库·spring boot·mysql·kafka
catoop5 小时前
Android 最佳实践、分层架构与全流程解析(2025)
android
ZHANG13HAO5 小时前
Android 13 特权应用(Android Studio 开发)调用 AOSP 隐藏 API 完整教程
android·ide·android studio
田梓燊6 小时前
leetcode 142
android·java·leetcode
angerdream6 小时前
Android手把手编写儿童手机远程监控App之JAVA基础
android
菠萝地亚狂想曲6 小时前
Zephyr_01, environment
android·java·javascript
sTone873757 小时前
跨端框架通信机制全解析:从 URL Schema 到 JSI 到 Platform Channel
android·前端
sTone873757 小时前
Java 注解完全指南:从 "这是什么" 到 "自己写一个"
android·前端
catoop7 小时前
Kotlin 协程在 Android 开发中的应用:定义、优势与对比
android·kotlin