安卓学习笔记34:默默工作的服务

零、学习目标

了解安卓组件“服务”的作用
掌握如何创建服务、注册服务
掌握如何启动服务和停止服务
掌握如何绑定服务和解绑服务

一、服务(Service)概述
(一)进程优先级

应用程序的生命周期是在Android系统中进程从启动到终止的所有阶段,也就是Android从启动到停止的全过程。Android应用程序的生命周期的终结这个动作并非由应用程序进程本身执行,而是取决于Android系统。那么,系统是根据一个怎样的重要性标准来终止Android应用程序呢?Android根据应用程序的组件以及组件当前运行状态将所有的进程按重要性程度从高到低划分为五个,如下图所示:
在这里插入图片描述

前台进程(完全可见的执行Activity)
可见进程(局部可见的执行Activity)
服务进程
后台进程(完全不可见的执行Activity)
空进程(是为了缓存进程,便于下次更快启动)

当执行一个安卓应用程序,如果运行内存不足,安卓系统会按上述优先级杀死进程。

(二)服务的作用

Service生命力顽强,它有两方面的作用:后台运行、跨进程访问。学习Service基础,利用它可以在后台完成一些耗时的工作,比如网络连接、下载数据、播放音频、播放视频等等。

(三)服务的生命周期

在这里插入图片描述

Service从启动到销毁只有三个阶段:创建服务、开始服务(启动、绑定)、销毁服务。
这三个阶段对应三个回调方法:onCreate()、onStartCommand() / onBind()、onDestroy()。
服务启动时,执行一次onCreate()方法与onStartCommand()方法,再次启动服务,不会再执行onCreate()方法,但是会再执行onStartCommand()方法。停止和解绑服务时,都会执行onDestroy()方法。

二、案例演示 - 启动与停止服务
(一)运行效果

在这里插入图片描述
在这里插入图片描述
(二)涉及知识点

线性布局(LinearLayout)
按钮(Button)
服务(Service)
线程(Thread)
Runnable接口
日志类(Log)

(三)实现步骤
1、创建安卓应用【StartStopService】

在这里插入图片描述
在这里插入图片描述
2、将背景图片拷贝到drawable目录

在这里插入图片描述
3、主布局资源文件activity_main.xml

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>

<Button
    android:id="@+id/btnExplicitlyStartService"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="@string/explicitly_start_service"
    android:onClick="doExplicitlyStartService"
    android:textSize="20sp"/>

<Button
    android:id="@+id/btnImplicitlyStartService"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="@string/implicitly_start_service"
    android:onClick="doImplicitlyStartService"
    android:textSize="20sp"/>

<Button
    android:id="@+id/btnStopService"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="@string/stop_service"
    android:onClick="doStopService"
    android:textSize="20sp"/>
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

4、字符串资源文件strings.xml

在这里插入图片描述

启动与停止服务 显式启动服务 隐式启动服务 停止服务
1
2
3
4
5
6

5、创建自定义服务类 - CustomService

继承Service类,创建CustomService类
在这里插入图片描述

声明变量与常量
在这里插入图片描述

在onCreate()方法里输出调试信息
在这里插入图片描述

在onStartCommand()方法里启动服务
在这里插入图片描述

在onDestroy()方法里停止服务
在这里插入图片描述

查看自定义服务类完整源代码

package net.hw.start_stop_service;

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

import androidx.annotation.Nullable;

/**

  • 功能:自定义服务类

  • 作者:华卫

  • 日期:2020年12月29日
    */
    public class CustomService extends Service {

    private final String TAG = “start_stop_service”; // 标记
    private Thread thread; // 线程
    private boolean isRunning; // 线程循环控制变量

    @Override
    public void onCreate() {
    super.onCreate();
    Log.d(TAG, “CustomService.onCreate() invoked.”);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, final int startId) {
    Log.d(TAG, “CustomService.onStartCommand() invoked.”);
    // 设置线程循环控制变量为真
    isRunning = true;
    // 判断意图是否为空
    if (intent != null) {
    // 创建线程
    thread = new Thread(new Runnable() {
    @Override
    public void run() {
    while (isRunning) {
    Log.d(TAG, "服务正在进行中……startId: " + startId + ", hashCode: " + CustomService.this.hashCode());
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    });
    // 启动线程
    thread.start();
    }
    // 设置服务的非粘性
    return Service.START_NOT_STICKY;
    }

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

    @Override
    public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, “CustomService.onDestroy() invoked.”);
    isRunning = false;
    thread = null; // 销毁线程
    stopSelf(); // 停止服务
    }
    }

    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
    68
    69

6、在项目清单文件里注册自定义服务类

在这里插入图片描述
7、主界面类 - Mainactivity

在这里插入图片描述

编写代码显式启动服务
在这里插入图片描述

编写代码隐式启动服务
在这里插入图片描述

编写代码停止服务
在这里插入图片描述

查看主界面类完整源代码

package net.hw.start_stop_service;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 利用布局资源文件设置用户界面
    setContentView(R.layout.activity_main);
}

/**
 * 显式启动服务
 *
 * @param view
 */
public void doExplicitlyStartService(View view) {
    // 创建启动指定服务的意图
    Intent intent = new Intent(this, CustomService.class);
    // 按照意图启动指定服务
    startService(intent);
}

/**
 * 隐式启动服务
 *
 * @param view
 */
public void doImplicitlyStartService(View view) {
    // 创建意图
    Intent intent = new Intent();
    // 设置意图动作(暗号或频道)
    intent.setAction("custom_service");
    // 设置意图包名
    intent.setPackage(getPackageName());
    // 按照意图启动服务
    startService(intent);
}

/**
 * 停止服务
 *
 * @param view
 */
public void doStopService(View view) {
    // 创建启动指定服务的意图
    Intent intent = new Intent(this, CustomService.class);
    // 按意图停止服务
    stopService(intent);
}

}

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

8、启动应用,查看效果
(1)显式启动服务 + 停止服务

在这里插入图片描述
在这里插入图片描述
服务的生命周期方法:

onCreate()——只执行一次,一般进行初始化工作
onStartCommand——执行多次(每次启动服务都会调用它)
onDestroy()——只执行一次,一般进行扫尾工作

(2)隐式启动服务 + 停止服务

在这里插入图片描述
在这里插入图片描述
三、案例演示 - 绑定与解绑服务
(一)运行效果

在这里插入图片描述
(二)涉及知识点

线性布局(LinearLayout)
按钮(Button)
服务(Service)
日志类(Log)

(三)实现步骤
1、创建安卓应用【BindUnbindService】

在这里插入图片描述
在这里插入图片描述
2、将背景图片拷贝到drawable目录

在这里插入图片描述
3、主布局资源文件activity_main.xml

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>

<Button
    android:id="@+id/btnBindService"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:onClick="doBindService"
    android:text="@string/bind_service"
    android:textSize="20sp" />

<Button
    android:id="@+id/btnUnbindService"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:onClick="doUnbindService"
    android:text="@string/unbind_service"
    android:textSize="20sp" />
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

4、字符串资源文件strings.xml

在这里插入图片描述

绑定与解绑服务 绑定服务 解绑服务
1
2
3
4
5

5、创建自定义服务类 - CustomService

在这里插入图片描述

声明常量
在这里插入图片描述

编写创建回调方法
在这里插入图片描述

编写绑定回调方法
在这里插入图片描述

编写销毁回调方法
在这里插入图片描述

查看自定义服务类完整源代码

package net.hw.bind_unbind_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;

/**

  • 功能:自定义服务类

  • 作者:华卫

  • 日期:2020年12月29日
    */
    public class CustomService extends Service {

    private final String TAG = “bind_unbind_service”; // 标记

    @Override
    public void onCreate() {
    super.onCreate();
    Log.d(TAG, “CustomService.onCreate() invoked.”);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    Log.d(TAG, “CustomService.onBind() invoked.”);
    // 获取从窗口传递过来的数据
    String message = intent.getStringExtra(“message”);
    // 显示数据
    Log.d(TAG, “恭喜,成功绑定服务!主窗口传递的数据:” + message);
    // 返回绑定器对象
    return new Binder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, “CustomService.onDestroy() invoked.”);
    }
    }

    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

6、在项目清单文件里注册自定义服务类

在这里插入图片描述
7、主界面类 - MainActivity

在这里插入图片描述

声明常量与变量
在这里插入图片描述

编写代码绑定服务
在这里插入图片描述

编写代码解绑服务
在这里插入图片描述

重写销毁回调方法
在这里插入图片描述

查看主界面类完整源代码

package net.hw.bind_unbind_service;

import android.app.Service;
import android.content.ComponentName;
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 androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

private final String TAG = "bind_unbind_service"; // 标记
private ServiceConnection conn; // 服务连接对象

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

/**
 * 绑定服务
 *
 * @param view
 */
public void doBindService(View view) {
    // 创建意图,显式指明要绑定的服务
    Intent intent = new Intent(MainActivity.this, CustomService.class);
    // 让意图携带数据
    intent.putExtra("message", "安卓开发真是有趣~");
    // 创建服务连接对象
    conn = new ServiceConnection() {

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

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "服务已经连接~");
        }
    };
    // 按意图绑定服务
    bindService(intent, conn, Service.BIND_AUTO_CREATE);
}

/**
 * 解绑服务
 *
 * @param view
 */
public void doUnbindService(View view) {
    // 判断服务连接是否为空
    if (conn != null) {
        // 解绑服务
        unbindService(conn);
    }
}

/**
 * 销毁窗口时解绑服务
 */
@Override
protected void onDestroy() {
    super.onDestroy();
    // 判断服务连接是否为空
    if (conn != null) {
        // 解绑服务
        unbindService(conn);
    }
}

}

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
68
69
70
71
72
73
74
75
76
77

8、启动应用,查看效果

在这里插入图片描述
在这里插入图片描述
四、小结

本次课,我们学习了如何创建服务、注册服务,以及如何启动或绑定服务。我们知道了,在主窗口可以启动或绑定服务,并且可以利用意图将数据传递给后台默默工作的服务,但是现在有一个问题,后台服务完成工作的进度如何传递给前台的窗口并以某种方式显示给用户看呢?那就要用到我们下一讲涉及的内容——广播接收者(BroadcastReceiver)。
对于活动窗口(Activity)、服务(Service)与广播接收者(BroadcastReceiver)三个安卓核心组件,需要掌握Activity与Service之间如何利用BroadcastReceiver实现相互通信,这个知识点在我们后面的实训项目《基于媒体库音乐播放器》中会用到。

五、课后作业
任务1、启动服务传递数据

界面如下图所示
在这里插入图片描述
输入数据,单击【启动服务】按钮两次,查看LogCat
在这里插入图片描述

任务2、绑定服务传递数据

界面如下图所示
在这里插入图片描述
输入数据,单击四次【绑定服务】,查看LogCat
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MATLAB中,NURBS(非均匀有理B样条)是一种强大的数学工具,用于表示和处理复杂的曲线和曲面。NURBS在计算机图形学、CAD(计算机辅助设计)、CAM(计算机辅助制造)等领域有着广泛的应用。下面将详细探讨MATLAB中NURBS的绘制方法以及相关知识点。 我们需要理解NURBS的基本概念。NURBS是B样条(B-Spline)的一种扩展,其特殊之处在于引入了权重因子,使得曲线和曲面可以在不均匀的参数空间中进行平滑插值。这种灵活性使得NURBS在处理非均匀数据时尤为有效。 在MATLAB中,可以使用`nurbs`函数创建NURBS对象,它接受控制点、权值、 knot向量等参数。控制点定义了NURBS曲线的基本形状,而knot向量决定了曲线的平滑度和分布。权值则影响曲线通过控制点的方式,大的权值会使曲线更靠近该点。 例如,我们可以使用以下代码创建一个简单的NURBS曲线: ```matlab % 定义控制点 controlPoints = [1 1; 2 2; 3 1; 4 2]; % 定义knot向量 knotVector = [0 0 0 1 1 1]; % 定义权值(默认为1,如果未指定) weights = ones(size(controlPoints,1),1); % 创建NURBS对象 nurbsObj = nurbs(controlPoints, weights, knotVector); ``` 然后,我们可以用`plot`函数来绘制NURBS曲线: ```matlab plot(nurbsObj); grid on; ``` `data_example.mat`可能包含了一个示例的NURBS数据集,其中可能包含了控制点坐标、权值和knot向量。我们可以通过加载这个数据文件来进一步研究NURBS的绘制: ```matlab load('data_example.mat'); % 加载数据 nurbsData = struct2cell(data_example); % 转换为cell数组 % 解析数据 controlPoints = nurbsData{1}; weights = nurbsData{2}; knotVector = nurbsData{3}; % 创建并绘制NURBS曲线 nurbsObj = nurbs(controlPoints, weights, knotVector); plot(nurbsObj); grid on; ``` MATLAB还提供了其他与NURBS相关的函数,如`evalnurbs`用于评估NURBS曲线上的点,`isoparm`用于生成NURBS曲面上的等参线,以及`isocurve`用于在NURBS曲面上提取特定参数值的曲线。这些工具对于分析和操作NURBS对象非常有用。 MATLAB中的NURBS功能允许用户方便地创建、编辑和可视化复杂的曲线和曲面。通过对控制点、knot向量和权值的调整,可以精确地控制NURBS的形状和行为,从而满足各种工程和设计需求。通过深入理解和熟练掌握这些工具,可以在MATLAB环境中实现高效的NURBS建模和分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值