android四大组件之一——Service

Android四大组件系列5 Service启动流程 一 概述 Service 的启动流程还是比较简单的,不像 Activity 那么复杂,相关联的类和方法也少了很多,不像 Activity 启动流程里面走着走着就会迷失方向,在上一篇文章我们主要分析了 Activity 的启动过程,今天我们主要来探索 Service 的启动过程。 Service 是 Android 四大组件,地位仅次于 Activity,Activity 位于前台向用户展示界面;Service 位于后台不可见,但是它承担了大部分的的数据处理工作,主要为其他组件提供后台服务,监控其他组件的运行 阅读详情
AI摘要

本文详细介绍了Android中Service的相关知识,包括概述、分类、启动方式、权限、生命周期等。还阐述了组件与绑定Service的三种通信方式:扩展Binder类、Messenger信使和AIDL,并分析了它们的使用场景区别,最后提供了源码下载链接。

​

目录

​一、Service概述

二、Service分类

1.前台服务

2.后台服务

3.绑定服务

三、Service的两种启动方式

1.start启动模式 

2.bind绑定模式

四、权限

五、Service生命周期

六、组件与绑定Service的通信方式

1.扩展 Binder 类

2.Messenger信使

3.AIDL

七、总结

场景使用区别

八、源码下载


一、Service概述

Service 是应用组件,代表一个应用的长时间后台运行的操作,没有交互界面,提供给其他应用一些功能。每个service类必须在清单文件AndroidManifest.xml里做 <service>声明. Services可以被启动通过Context.startService() 和Context.bindService().

services像其他应用对象一样,运行在宿主进程的主线程。这意味着,如果你的服务要执行任何CPU密集型(如MP3播放)或阻塞(如网络)操作,它应该生成自己的线程来完成这项工作。有在Processes and Threads中可以找到更多的信息。 JobIntentService 类作为标准实现类,它有自己的线程可以按部就班的处理事务。

Service 是 应用组件 长时间运行的操作。它不提供界面。一次 一项服务可能会继续运行一段时间,即使用户切换到另一项服务 应用。此外,组件可以绑定到服务以与其进行交互,甚至执行 进程间通信 (IPC)。例如,服务可以处理网络事务、 音乐、执行文件 I/O 或与内容提供程序互动,所有这一切都可以在后台进行。

关于Service类的许多困惑实际上都围绕着它不是什么:

Service不是一个独立的进程。Service对象本身并不意味着它在自己的进程中运行;除非另有指定,否则它在其所属的应用程序相同的进程中运行。
Service不是一个线程。它本身不是一种在主线程之外执行工作的手段(以避免应用程序无响应错误)。
Service实际上非常简单,提供了2个主要功能:

一个功能是允许应用程序在后台运行处理事情 (甚至不需要有交互界面).当请求系统定时去处理事务时,可以调用 Context.startService()启动Service,一直运行Service,除非用户明确停止Service.
一个功能是应用程序可以提供给其他应用一些功能,当为了与服务交互保持长期的连接时,可以调用Context.bindService(),绑定Service.
当Service组件被创建时,系统会实例化这个组件,并且会在主线程中回调onCreate()等方法。Service是否可以用适当的操作实现这些操作,例如创建一个可以工作的辅助线程。

因为Service如此简单,所以你可以通过想用的简单的或者复杂的方式与它交互。把Service当作Java本地对象,创造直接的回调方法(详细说明请看本地Service示例)通过AIDL提供全部远程接口。

二、Service分类

Service的三种类型如下:

1.前台服务

前台服务与后台服务不同的是,前台服务一般用于执行一些用户能注意到的操作。例如:音频应用会使用前台服务来播放音频曲目,位置信息提醒,通知栏显示导航信息等场景后可以使用前台服务。前台服务必须显示通知,即使用户停止与应用交互,前台服务仍会继续运行。因为它是用户可以感知到存在的,所以前台服务的优先级比较高,等同与一个处于前台的 Activity 的优先级,几乎不太可能被系统杀掉。

前台服务用于执行用户可以注意到的操作。前台服务会显示状态栏通知。Android 9.0及之后,要求必须申请如下权限才能使用前台服务:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

如果在前台服务中要实现用户的位置,或者要使用相机等,还需要申请一些更具体的权限,官网有详细说明,这里就不展开说了。

注意:在Android 12以上运行前台服务,系统会等待 10 秒,然后才会显示与前台服务关联的通知.

前台服务demo源码请见:章节八、源码下载

2.后台服务

后台服务一般用于执行用户不会直接注意到的操作。例如,如果应用在后台使用某个服务来压缩其存储空间,则此服务通常是后台服务。一般来说,可以通过startService(intent)方法来启动一个后台服务。

3.绑定服务

当应用组件通过 bindService() 绑定到服务时,服务即处于绑定状态(此时可以将service看作是服务器,绑定的组件看作是客户端),绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接受结果,甚至是利用进程间通信跨进程执行这些操作,仅当与另一个应用组件绑定时,绑定服务才会运行,多个组件可同时绑定到同一个服务,全部取消绑定后,该服务会被销毁。这种service的形式是比较常用的。

注意:只有 Activity、Service和内容提供程序可以绑定到服务,无法从广播接收器绑定到服务。

三、Service的两种启动方式

系统启动Service有两种方式:startService和bindService

1.start启动模式 

通过调用Context.startService() 启动Service,然后系统检索到service后,创建它,并调用onCreate,然后通过客户端提供的参数回调onStartCommand(Intent, int, int)方法。 service会一直运行,直到调用Context.stopService() 或stopSelf() 停止Service.

请注意,对Context.startService()的多次调用不会嵌套 (多次调用start会回调多次onStartCommand()方法), 所以无论启动多少次service,只要调用一次Context.stopService() 或者stopSelf(),Service就会被停止。无论怎样,services可以用 stopSelf(int) 方法确保只有在intents开始处理后,才能停止service。

对于已经启动的services, 它们还可以选择以另外两种主要的运行模式运行,依赖于onStartCommand()的返回值: START_STICKY,表示services当被需要时,会被明确的启动或者停止。当使用START_NOT_STICKY or START_REDELIVER_INTENT 于服务时,服务当处理任何指令发送它们时,服务应该一直保持运行。详情请参考有关文档。

start启动模式demo源码下载请见:章节八、源码下载

2.bind绑定模式

客户端也可以用Context.bindService()获取与service的持续连接。同样创建没有运行的服务,但是不回调onStartCommand()方法. 客户端可以收到从服务  onBind(Intent)方法返回的IBinder 对象,允许客户端制造回调给service。service运行时长和连接建立时长一样。通常 IBinder被返回给在aidl中创建的复杂接口。

service可以被启动或者绑定。在这种情况下,系统可以保持service运行只要它被启动或者被绑定通过 Context.BIND_AUTO_CREATE 标识. 一旦这两种情况都不成立后,service的onDestroy() 方法会被调用或者有效的中断。所有的清理工作也应该在onDestroy()方法返回之前.

注意,当调用unbindService(connection)时ServiceConnection中的onServiceDisconnected并没有被回调,这是应为这个方法只有在Service被不正常kill之后才会回调,通过这个回调是为了让用户知道服务被kill了,然后可以重新启动服务。

bind启动模式demo源码下载请见:章节八、源码下载

四、权限

当一个服务在其清单文件(manifest)的<service>标签中被声明时,可以强制实现对该服务的全局访问。通过上述操作,其他应用也需要声明对应的权限<uses-permission> 在自己的清单文件里,用以启动,停止,或绑定service.

从Build.VERSION_CODES.GINGERBREAD(即Android 2.3姜饼版本)开始,当使用Context.startService(Intent)方法启动服务时,您还可以在Intent上设置Intent.FLAG_GRANT_READ_URI_PERMISSION和/或Intent.FLAG_GRANT_WRITE_URI_PERMISSION标志。这将授予服务对Intent中特定URI的临时访问权限。该访问权限将一直保留,直到服务为该启动命令或后续命令调用了stopSelf(int)方法,或者服务已经完全停止为止。

这适用于向那些没有请求保护服务的权限的其他应用授予访问权限,甚至当服务根本没有被导出时也同样有效。

另外,service可以用权限保护IPC调用,在执行调用实现之前需要调用ContextWrapper.checkCallingPermission(String) 方法。

查看Security and Permissions 文档,大体上详细讲述了权限和安全的内容。

五、Service生命周期

onCreate()

首次创建服务时,系统会在调用 onStartCommand()或onBind() 之前调用onCreate()方法来执行一次性设置程序。如果服务已在运行,则不会调用此方法。

onStartCommand()

内部其实调用了服务的onStart,所以onStart()这个生命周期已被弃用。

每次执行startService(intent)时,都会回调Service的onStartCommand生命周期。在执行bindService(intent)时,是不会回调Service的onStartCommand的

如果系统终止了服务,那么会在资源可用时立即重启服务。这取决于你的onStartCommand()的返回值。

onDestroy()

作为后台服务/前台服务时,当我们手动调用stopService(intent)或stopSelf()方法的时候,服务就停止了。然后回调onDestroy()。

作为绑定服务时,当我们调用unbindService(connection)时,服务就停止了。然后回调onDestroy()。

服务应通过实现onDestroy()方法来清理任何资源,如线程、注册的监听器、接收器等。

onBind()

Service的成员方法。返回一个IBinder对象。

当我们把服务作为一个绑定服务的时候,才会用到这个回调方法。如果Service是后台服务的形式,一般是不需要用到这个方法的。在Service是绑定的形式时,需要实现这个方法。

作为绑定服务时,当我们调用bindService()时,回调完onCreate()方法,就会马上回调onBind()方法。

onUnbind()

同理,当服务作为绑定服务时,当我们调用unbindService(connection)时,就会回调onUnbind()方法。

onStartCommand返回值
当调用startService(intent)方法启动Service时,会回调Service的onStartCommand生命周期。

如果面临资源匮乏时,系统可能会销毁掉当前运行的Service,然后待内存充足的时候可以重新创建Service,Service被强制销毁并再次重建的行为,依赖于Service中onStartCommand方法的返回值,下面我来列举几个它的常用的返回值:

  • START_NOT_STICKY:如果onStartCommand返回该值,表示当Service被强杀后,不会重新创建该Service。
  • START_STICKY:当Service被强杀后,系统仍会将该Service设置为运行状态,但是不再保存onStartCommand方法传入的intent对象,当系统资源充足时,会尝试再次重新创建该Service,并执行onStartCommand回调方法,但是onStartCommand回调方法的Intent参数为null。这也是onStartCommand的默认的返回值。
  • START_REDELIVER_INTENT:该返回值与START_STICKY类似,不同的是,系统会保留Service被强杀前的最后一次传入onStartCommand方法中的Intent对象。

只要服务已被启动或有客户端绑定到该服务,Android系统就会尝试保持承载该服务的进程存活。当内存低时,需要杀死进程,保留service的进程根据下面可能性有更高的优先级:

大多数时候,运行着的service,在内存高度紧缺的情况下,依旧可能被kill掉。如果被kill掉,系统会在稍后重启service。这带来的一个重要后果是,如果您在onStartCommand()方法中安排异步执行工作或在其他线程中执行工作,那么您可能希望使用START_FLAG_REDELIVERY标志,以便系统在您的服务在处理Intent时被终止的情况下重新传递该Intent,从而确保它不会丢失。

当然,与服务运行在同一进程中的其他应用程序组件(如Activity)可以提高整个进程的重要性,而不仅仅是服务本身的重要性。

六、组件与绑定Service的通信方式

对用于service中,一般使用bindService()启动服务。这是一种比startService更复杂的启动方式,同时使用这种方式启动的service也能完成更多的事情,比如其他组件可向其发送请求,接受来自它的响应,甚至通过它来进行IPC等等。我们通常将绑定它的组件称为客户端,而称它为服务端。 如果要创建一个支持绑定的service,我们必须要重写它的onBind()方法。这个方法会返回一个IBinder对象,它是客户端用来和服务器进行交互的接口。而要得到IBinder接口,我们通常有三种方式:继承Binder类,使用Messenger类,使用AIDL。

跨进程通信方式有如下三种:

  • 扩展Binder类
  • Messenger信使
  • AIDL

后面两种可以跨进程通信,是基于Binder机制的通信方式。第一种我们多用于service直接的通信,但是当sevice被设为远程服务时(设为:remote),我们就要用后面两种方式来进行通信了。

Android系统中,如果组件与服务通信是在同一进程,就使用第一种方式;如果是跨进程通信,使用第二种和第三种,两者不同在于,Messenger不能处理多线程并发请求。​

1.扩展 Binder 类

直观来说,Binder是Android中的一个类,它集成了IBinder接口。

从IPC角度来说,Binder是Android中的一种跨进程通信方式;

Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没有;

从AndroidFramework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager,等等)和相应ManagerService的桥梁;

从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

如果我们的服务仅供本应用使用,无需跨进程,则可以实现自有 Binder 类,让客户端通过 Binder 类直接访问 Binder 或 Service 中提供的公共方法

如果您的服务仅对您自己的应用专用,并且在同一进程中运行 作为客户端(这很常见),请通过扩展 Binder 来创建接口 类别 并从中返回一个 onBind()。客户端收到 Binder 后,可利用它直接访问 Binder 实现或 Service 中提供的公共方法。

如果服务只是您自有应用的后台工作器,应优先采用这种方式。只有在这并非创建接口的首选方式时, 如果其他应用或不同的进程使用您的服务,则会发生该错误。

如果只有本地应用使用您的服务,且无需 跨进程工作 那么您可以实现自己的 Binder 类,为您的客户端直接提供 访问服务中的公共方法。

注意:只有当客户端和服务处于同一应用和进程内(最常见的情况)时,此方式才有效。例如,这非常适合于 这个应用需要将一个 activity 绑定到自己在 背景。

以下为设置方式:

  • 在您的服务中,创建可执行以下某种操作的 Binder 实例:

包含客户端可调用的公共方法。
返回当前的 Service 实例,该实例中包含客户端可调用的公共方法。
返回由服务承载的其他类的实例,其中包含客户端可调用的公共方法。

  • 从 onBind() 回调方法返回此 Binder 实例。
  • 在客户端中,从 onServiceConnected() 回调方法接收 Binder,并使用提供的方法调用绑定服务。

注意:服务和客户端必须在同一应用内,这样客户端才能转换返回的对象并正确调用其 API。服务 和客户必须在同一进程中,因为此方法不会执行任何 是跨进程编组的

举例

例如,以下服务可让客户端通过 Binder 实现访问服务中的方法:

服务端代码(MyService.kt)和客户端代码(ServiceDemoActivity.kt)demo项目源码下载请见:

章节八、源码下载

注意:不要使用远程服务,如果一定要使用远程服务就要用后面的两种跨进程方式。

2.Messenger信使

如需让接口跨不同进程工作,您可以使用 Messenger 为服务创建接口。这样,服务 定义了一个 Handler,用于响应不同类型的 Message 对象。

这部Handler 是 Messenger 的基础,后者随后可以共享 IBinder 与客户端连接起来,让客户端使用 Message 对象向服务发送命令。此外,客户端还可以定义一个 Messenger 它自己的,因此服务可以发回消息。

这是执行进程间通信 (IPC) 最为简单的方式,因为 Messenger 会在单个线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计。

如果您需要让服务与远程进程通信,则可使用 Messenger 为您的服务提供接口。利用这种方法, 无需使用 AIDL 即可执行进程间通信 (IPC)。

为接口使用 Messenger 比使用 AIDL 更简单,Messenger 会将所有服务调用加入队列,而纯 AIDL 接口会同时向服务发送多个请求,所以服务必须对多线程进行处理。对于大多数应用,服务无需执行多线程处理,因此使用 Messenger 可让服务一次处理一个调用。

如果我们的服务必须使用多线程,那么应该使用 AIDL 来定义接口。

以下是对 Messenger 使用方式的摘要:

  • 服务实现一个 Handler,由其接收来自客户端的每个调用的回调。
  • 服务使用 Handler 来创建 Messenger 对象(该对象是对 Handler 的引用)。
  • Messenger 创建一个 IBinder,服务通过 onBind() 将其返回给客户端。
  • 客户端使用 IBinder 将 Messenger(它引用服务的 Handler)实例化,然后再用其将 Message 对象发送给服务。
  • 服务在其 Handler 中(具体而言,是在 handleMessage() 方法中)接收每个 Message。
  • 这样,客户端便没有调用服务的方法。相反,客户端会传递服务在其 Handler 中接收的消息(Message 对象)。

举例

下面这个简单的服务实例展示了如何使用 Messenger 接口。

 如果您想让服务做出响应,还需在客户端中创建一个 Messenger。当客户端收到 onServiceConnected() 回调时,会向服务发送一个 Message,并在其 send() 方法的 replyTo 参数中加入客户端的 Messenger。如需查看如何提供双向消息传递的示例,请看如下示例:章节八、源码下载

服务端代码(MessengerService.kt)和客户端代码(MessengerActivity.kt)demo项目源码下载请见:

章节八、源码下载

3.AIDL

Android官方推出了AIDL(Android Interface Definition Language),它是基于Binder机制的。

Android 接口定义语言 (AIDL) 可将对象分解为 操作系统可以识别这些基元并将其编组到各进程中以执行 IPC。之前采用 Messenger 的方法实际上是以 AIDL 为基础, 及其底层结构。

如上一部分所述,Messenger 会创建一个 所有客户端请求都在一个线程中完成,因此服务一次接收一个请求。不过,如果您想让服务同时处理多个请求,可以直接使用 AIDL。在这种情况下,您的服务必须具备线程安全性,并且能够进行多线程处理。

如需直接使用 AIDL,请执行以下操作: 创建一个定义编程接口的 .aidl 文件。Android SDK 工具会利用该文件生成实现接口和处理 IPC 的抽象类,您随后可在服务内对该类进行扩展。

注意:对于大多数应用来说,AIDL 并不是 创建绑定服务,因为它可能需要多线程处理能力 可以使实现过程更加复杂。

注意:必须使用 Java 编程语言构建 .aidl 文件。

默认情况下,AIDL 支持下列数据类型:

所有基本数据类型(如 int、long、char、boolean 等)

  • String
  • CharSequence
  • List:List 中所有元素必须是以上列出的数据类型或者我们声明的由 AIDL 生成的其他接口或 Parcelable 类型。
  • Map:Map 中所有元素必须是以上列出的数据类型或者我们声明的由 AIDL 生成的其他接口或 Parcelable 类型。

注意:即使在与接口相同的包内定义了上方未列出的其他类型,也必须要通过 import 导入这些类型。

AIDL通信步骤

  • 创建一个.aidl文件,在其中定义接口和方法。

将该文件放置在src/main/aidl/<package_name>/目录下。

  • 在Service中创建一个继承自IMyService.Stub的内部类,并重写定义在AIDL接口中的方法。

在onBind方法中返回该内部类的实例作为Binder对象。

  • 将AIDL文件复制到客户端项目中。
  • 使用bindService方法绑定服务,并通过ServiceConnection回调获取Binder代理对象。
  • 通过该代理对象调用服务端定义的方法。

首先,当客户端发起远程请求时,由于当前线程会被挂起直至服务端进程返回数据,所以如果一个远程方法是很耗时的,那么不能在UI线程中发起此远程请求;其次,由于服务端的Binder方法运行在Binder的线程池中,所以Binder方法不管是否耗时都应该采用同步的方式去实现,因为它已经运行在一个线程中了。

举例

服务端代码(RemoteService.kt, IRemoteService)和客户端代码(ClientActivity.kt)demo项目源码下载请见:章节八、源码下载

七、总结

场景使用区别

那么,他们的使用场景分别是什么呢?

如果我们无需跨进程实现绑定服务和同一进程组件之间的通信,则使用 Binder 类即可
如果我们需要跨进程实现绑定服务和其他进程组件之间的通信,且不需要进行多线程处理时,则使用 Messenger
如果我们需要跨进程实现绑定服务和其他进程组件之间的通信,且需要进行多线程处理,则使用 AIDL.

首先,在实现的难度上,肯定是Messenger要简单的多——至少不需要写AIDL文件了(虽然如果认真的究其本质,会发现它的底层实现还是AIDL)。另外,使用Messenger还有一个显著的好处是它会把所有的请求排入队列,因此你几乎可以不用担心多线程可能会带来的问题。

但是这样说来,难道AIDL进行IPC就一无是处了么?当然不是,如果是那样的话它早就被淘汰了。一方面是如果项目中有并发处理问题的需求,或者会有大量的并发请求,这个时候Messenger就不适用了——它的特性让它只能串行的解决请求。另外,我们在使用Messenger的时候只能通过Message来传递信息实现交互,但是在有些时候也许我们需要直接跨进程调用服务端的方法,这个时候又怎么办呢?只能使用AIDL。

八、源码下载

IPC进程间通信demo、客户端(Activity)与服务端(Service)间通信demo,Messenger通信demo,下载源码请见:

https://download.youkuaiyun.com/download/github_27263697/90277464

参考文章

绑定服务概览  |  Background work  |  Android Developers

Android跨进程通信Binder、Messenger、AIDL汇总_安卓 amessage 和 binder-优快云博客

【Android】IPC 之 AIDL、Messenger 、Binder 浅析_安卓 amessage 和 binder-优快云博客

Binder机制原理和AIDL使用Binder机制概述 Binder是Android系统中用于不同进程间通信(IPC)的 - 掘金

​​​​​ Android 之IPC详解_android ipc-优快云博客

【Android】四大组件之 Service_service类型-优快云博客

Android Process 详解_android:process-优快云博客

Service  |  Android Developers

Android 四大组件之Service的详解 ** 一、Service的简介 ** Service是Android中实现程序后台运行的解决方案,适用于去执行那些不需要和用户交互而且还要求长期运行的任务。Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。 作用:提供 需在后台长期运行的服务 特点:无用户界面、在后台运行、生命周期长 1、Service的生命周期 阅读详情

相关推荐

Android service(服务)中的前台服务

前台服务是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。前台服务必须为状态栏提供通知,将其放在运行中的标题下方。这意味着除非将服务停止或从前台移除,否则不能清除该通知。针对上一篇文章中的案例我们可以发现,系统对后台服务进行了限制,如果想要一直保持服务的运行就需要将服务设置为前台服务。前台服务与普通服务的区别在于它会有个通知在状态栏显示,当然有时可能也不仅仅是为了防止服务被回收才使用前台服务,有些项目的需要要求必须使用前台服务。

superzhang6666的博客 9348

Android 服务(Service)详解

总结学习类文章 service(服务)是安卓中的四大组件之一,它通常用作在后台处理耗时的逻辑,与Activity一样,它存在自己的生命周期,也需要在AndroidManifest.xml配置相关信息。 服务(Service)是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。 不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖

weixin_40862356的博客 1万+

AWS入门实践-如何在AWS云上创建一个内外网隔离的生产环境

在 AWS 上建立一个内外网分离的生产环境,可以减少应用服务的暴露面,有效的保证你的应用服务器的安全。通常我们会将web应用放在外网的子网内,数据库服务器等放在内网的子网。我们将按照下图来部署动手实践环境,实现在public subnet的EC2虚拟机可以直接通过互联网可以访问,在Private subnet的EC2虚拟机不能通过互联网直接访问,但是却可以在内部来访问互联网安装应用等等。

weixin_39108752的博客 2993

关于Android Service真正的完全详解

Android Service完全详解

QG 3916

实战MSP-M0G3507与陶晶驰串口屏的通信协议解析

本文详细解析了MSP-M0G3507微控制器与陶晶驰串口屏的通信协议实现。内容涵盖串口配置、协议帧结构、数据校验机制及ASCII协议实战代码,重点介绍了陶晶驰串口屏的指令集应用和调试技巧,为嵌入式开发提供可靠的串口通信解决方案。

h9j8k7l6m5n的博客 866

NRF52832调试方法1——HardFault_Handler问题定位

一、遇到问题 keil debug模式下,直接点击全速运行(Run)发现程序卡死,点击stop按钮后,停到了HardFault_Handler位置,如下图所示。 此时使用navigate backwards(蓝色左箭头)是无效的,找不到程序卡在哪里。 二、解决办法 此时首先观察register窗口 若Stack为MSP,则复制R13(SP)的值到memory观察窗的地址搜索栏。每一行显示连续的28个地址上的存储信息,每个地址上存有一个字节。 从第21个位置起的连续四个字节是LR的值,

小梁的博客 3650

【Android】安卓四大组件之Service

【Android】安卓四大组件之Service 1、Service的介绍 1.1 什么是service Service即服务,用大白话讲就是——长期运行在后台的程序,如果我们说的官方一点,那么就是用于执行长期运行的任务,并且没有与用户交互的功能。 每一个service都和activity一样,需要在manifest.xml中配置,赋予其生命。使用<service>标签即可配置 在activity类中,可以使用Context.startService()方法来开启服务,使用Context.stop

woodwhale的博客 690

ComfyUI的G-Dino模型加载器报错解决方案:从崩溃到重生

遇到G-Dino模型加载器报错不要慌,按照本文的步骤操作,99%的问题都能解决。模型文件正确下载到指定位置segment_anything节点安装完整且无冲突需要补充更多细节或故障排除方法吗?可以随时告诉我。

2301_78150483的博客 4020

android四大组件(Activity,Service,BroadcastReceiver,Content Provider)

安卓的四大组建,五大布局Android四大组件:Activity、Service、Broadcast Receiver、Content Provider。1、 Activity 可以去本人博客activity了解学习是Android程序与用户交互的窗口,从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个

Mr_haimeng的博客 1358

Labview项目01:标准可配置序列测试框架

摘要:本文介绍了一个基于LabVIEW2020开发的通用测试框架系统。该系统采用模块化设计,包含主界面、调试界面、设置界面和登录界面。主功能包括:1)可配置测试序列,支持延时、预定值输出、随机值输出等操作;2)单步测试功能自主添加;3)界面支持测试序列编辑和权限管理。系统采用队列机制处理事件和测试流程,通过CSV文件存储测试序列,支持参数化配置。用户可自定义测试VI(A_.vi和N_.vi格式),并通过调试界面验证测试序列。最终测试结果在主界面显示,提供整体判断功能。该系统既可作为学习参考,也可用于实际测试

weixin_38637405的博客 1552

第六节 LLaVA模型数据处理源码解读(input_ids/labels/attention_mask/image,上篇)

本篇文章直接介绍llava模型数据加工部分,整体结构说明llava多模态模型输入数据格式,其中包含input_ids/labels/attention_mask与image格式,并给出对应代码位置与整个数据加工流程。最重要,通过debug给出数据解释与代码解读,也通过一个真实数据给出模型输入格式说明。当你阅读完此篇文章,绝对透彻理解llava数据加工过程与内容。显然,一篇博客是无法呈现整个数据细节,我将继续下篇博客呈现数据细节处理。result = input.ne(3) # torch.ne函数调用。

weixin_38252409的博客 3193

【Android】安卓四大组件之服务(Service)详解:从基础到进阶

Service作为安卓应用后台任务处理的核心组件,在保障应用功能完整性和提升用户体验方面起着不可或缺的作用。通过掌握Service的生命周期、分类及使用场景,开发者能够合理设计应用架构,实现高效、稳定的后台任务处理。随着安卓系统的不断升级,Service的使用也需与时俱进,结合新特性和替代方案,让应用在后台运行中发挥更大价值。希望本文能帮助大家深入理解Service,在安卓开发中灵活运用这一强大工具

m0_59734531的博客 1522

偏最小二乘回归分析原理详解和案例分析实例

偏最小二乘回归分析原理详解背景偏最小二乘回归分析 Partial least squares regression analysis基本思想建模步骤步骤一:分别提取两变量组的第一对成分,并使之相关性达最大步骤二:建立 y1,⋯ ,yp\boldsymbol{y}_{1}, \cdots, \boldsymbol{y}_{p}y1​,⋯,yp​ 对 u1\boldsymbol{u}_{1}u1​ 的回归及 x1,⋯ ,xm\boldsymbol{x}_{1}, \cdots, \boldsymbol{x}_{

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 9976

【Android】安卓四大组件之Service用法

使用Handler更新UI,基本特点后台执行Service主要用于在后台执行一些长时间运行的操作,比如音乐播放、文件下载等,而不会影响用户界面的交互。

Patrick_yuxuan的博客 1401

K230在原有LVGL控件触摸屏控制的基础上,增加USB鼠标控制!

搭配CanMV图形化编程,中小学生可快速开发“键鼠控制AI小游戏”“智能画板”等趣味项目,降低AI学习门槛;:HDMI屏幕+键鼠组合,直接在开发板上调试代码、修改ISP参数、查看AI推理日志,无需频繁连接电脑;:打造带交互的AI设备(如工业控制面板、智能显示器),鼠标操作菜单、键盘输入指令,体验媲美小型PC;:无网络场景下,通过键盘直接向AI设备录入数据、配置参数,适配野外监测、本地工控等场景。,自动识别、快速响应,完美适配交互控制、参数调试、数据输入等场景。

weixin_47446386的博客 145

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

安卓四大组件之service

Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色,所以每一位安卓工程师对其掌握是必然的!针对Service,优快云博客之星–郭霖写了两篇比较完整的解析博客: Android Service完全解析,关于服务你所需知道的一切(上) Android Service完全解析,关于服务你所需知道的一切(下)

探路的淮--Ontheway的博客 951

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Android四大组件之Service

https://developer.android.google.cn/guide/components/services.html本篇博客讲解的是Android四大组件之Service,下面是内容摘要: 了解Service Android 中的进程 电话窃听器 Service 的生命周期 AIDL的使用 一、Service 的基本概念Android 官方文档对Service 的解释如下:A Ser

JackChan 1176

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android四大组件应用app,安卓四大组件———Service

1.什么是Service(服务)Service是一种后台运行的应用组件。2.Service有哪些应用场景下载任务,qq消息缓存,音乐播放器的播放3.startService方式启动Service怎么做()首先新建一个类继承Service ,实现它的onBind方法,其中可以用onCreate(),onStartCommand()和onDestroy()方法。例如package com.exampl...

weixin_30395941的博客 513

安卓开发四大组件及Service

对于activity和服务来说,它指明了请求的操作名称以及作为操作对象的数据的URI和其他一些信息。比方说,它能够承载对一个activity 的请求,让它为用户显示一张图片,或者让用户编辑一些文本。广播i接收器没有用户界面,但可以启动一个activity或service来响应收到的信息,或用NotificationManager来通知用户。静态注册无需担忧是否被关闭,只要设备是开启状态,广播接收器也是打开的。使用URI唯一标识其数据集,这里的URI以content://作为前缀,表示数据由其管理。

gfdr5的博客 297

安卓四大组件之Service

Service作为安卓四大组件之一通常用来完成一些不需要用户操作,但是一直运行着的任务  在介绍Service之前 我们先了解一下安卓中进程的优先级: 安卓中的优先级共有5个 1.Foregrounf process 前台进程  当前进程中有Activity处于可见可操作(Activity执行onResume之后) service 以及广播接收者 执行生命周期方法 2.vi

ybx007的博客 511

Android 四大组件之Service

Service是android系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,区别是Service只能运行在后台不提供用户界面,并且可以和其他组件进行交互。一个Service是一个可以长期运行在后台的应用程序组件,不提供用户界面。 另一个应用程序组件可以启动一个服务,它将继续在后台运行,...

ZHS_Vistor的博客 474

安卓四大组件 —— Service

1、什么是service? service是android四大组件之一,是可以在后台长期执行并且没有用户界面的程序组件;只能运行在主线程中,不能做耗时操作,可以跨程序调用。 2、service有哪些应用场景? 当程序中的某项功能执行时间较长(如:下载,上传等)并且在执行过程中不需要用户操作,不需要Activity进行交互的情况下,可以通过service在后台完成指定任务。 3、starSe...

s15770702468的博客 728

Android——四大组件Service

文章目录AndroidAndroid四大组件——Service1 简介2 生命周期3 Service分类3.1 started(启动服务)3.2 bound(绑定服务)IBinder接口ServiceConnection接口 Android Android四大组件——Service service用于在后台完成用户指定的操作。 startService() 与 bindService()区别: (a)started service(启动服务)是由其他组件调用startService()方法启动的,这导致服

weixin_45044097的博客 300
上一篇: Android详解——ConstraintLayout约束布局
下一篇: Kotlin中is,!is,as和as?运算符的区别
闲暇部落
博客等级 码龄12年 2775粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值