当前位置: 首页 > news >正文

简单记录一下Android四大组件

1、Android Layout

1.1、LinearLayout

线性布局,子控件按照水平或垂直的方向依次排列,排列方向通过属性android:orientation控制,horizontal为水平排列,vertical为垂直排列。对于同一水平线上的控件,可以调整它的layout_width或者layout_height为0,然后通过layout_weight来进行比例计算。

如果想要将多个控件进行换行,可以再次添加LinearLayout,将该layout的layout_width或者layout_height设置为match_parent。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="Button 1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="Button 2"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="2"android:text="Button 3"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="Button 4"/></LinearLayout></LinearLayout>

参考:
请添加图片描述

1.2、RelativeLayout

RelativeLayout是通过控件之间的相对位置关系来进行限制或布局的,在默认情况下,子控件出现在父容器的左上角。

相对位置关系控制分为两个方面,一个是相对于父容器布局,还有一种是相对于其他控件布局。

  • 相对父容器布局,主要是限制控件在父容器边缘的位置
    • android:layout_alignParentLeft
    • android:layout_alignParentRight
    • android:layout_centerHorizontal:水平居中
    • android:layout_alignParentTop
    • android:layout_alignParentBottom
    • android:layout_centerVertical:垂直居中
    • ndroid:layout_centerInParent:水平垂直居中
  • 相对其他控件布局
    • android:layout_toLeftOf
    • android:layout_toRightOf
    • android:layout_above
    • android:layout_below
    • android:layout_alignTop:顶部对齐
    • android:layout_alignBottom
    • android:layout_alignLeft
    • android:layout_alignRight
  • 边距设置:限制控件与父容器或者其他控件之间的边距,准确控制控件位置
    • android:layout_marginLeft
    • android:layout_marginRight
    • android:layout_marginTop
    • android:layout_marginBottom

参考:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/button0"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentBottom="true"android:layout_marginRight="20px"android:layout_marginBottom="20px"android:text="Button 0" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="50px"android:layout_marginLeft="50px"android:text="Button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignTop="@id/button1"android:layout_marginLeft="30dp"android:layout_toRightOf="@+id/button1"android:text="Button 2" /></RelativeLayout>

请添加图片描述

1.3、FrameLayout

FrameLayout中,不做额外设置,所有子控件会堆叠在布局左上角,后添加的控件会覆盖先添加的控件。

该布局下对控件的限制方式比较单一,先限制子控件相对父容器的对齐方式,然后具体限制位置。

  • 对齐方式定位使用android:layout_gravity实现,常用取值如下:
    • top
    • bottom
    • left
    • right
    • center:水平垂直居中
    • center_horizontal
    • center_vertical
  • 边距位置调整:
    • android:layout_marginLeft
    • android:layout_marginRight
    • android:layout_marginTop
    • android:layout_marginBottom
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/ic_launcher"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Hello, World!"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 0"android:layout_gravity="top|right"android:layout_marginRight="30dp"/></FrameLayout>

请添加图片描述

1.4、ConstraintLayout

ConstraintLayout有三种约束方式,分别为相对位置约束、居中(比例)约束、尺寸约束、链条约束

1.4.1、相对位置约束

相对位置约束指的是将控件的四个维度与其他控件对齐,至少限制两个维度才能确认这个控件的位置。相对于父容器和其他控件的常用限制方式有:

  • app:layout_constraintLeft_toLeftOf
  • app:layout_constraintLeft_toRightOf
  • app:layout_constraintRight_toRightOf
  • app:layout_constraintTop_toTopOf
  • app:layout_constraintBottom_toBottomOf

名称要分为两部分看,一部分是下划线中间的部分,表示限制控件的那个维度(left、right、top、bottom);另一部分是最后边,表示如何限制(被对齐控件的维度),每个维度有两种限制方式,比如说left,可以让控件的左端对齐到其他控件或容器的右端,也可以对齐到其他控件的左端,所以说有layout_constraintLeft_toLeftOf和layout_constraintLeft_toRightOf两种约束方式。当然其他维度也是有两种约束方式。

如果要限制具体的距离大小,可以通过:

  • android:layout_marginLeft
  • android:layout_marginRight
  • android:layout_marginTop
  • android:layout_marginBottom

1.4.2、居中约束

我觉得这也可以称为比例约束,上面说至少要限制两个维度,如果既限制了控件的左边,又限制了控件的右边(同时添加layout_constraintLeft_toLeftOf和layout_constraintLeft_toRightOf),那么它会处在一个居中位置(复杂情况暂不研究)。如果想要调整左右比例,可以使用:

  • app:layout_constraintHorizontal_bias

1.4.3、尺寸约束

控件的尺寸在ConstraintLayout中又如下几种限制方式:

  • 固定尺寸:使用android:layout_width 和 android:layout_height 属性设置控件的固定宽度和高度。
  • 根据约束调整尺寸:如果将layout_width设置为0,又同时设置了layout_constraintLeft_toLeftOf和layout_constraintLeft_toRightOf,那么这时候这个控件的宽度会自动调整为整个父容器的宽度;
  • 比例尺寸:在上述条件下,自动调整尺寸时,可以设置宽高比例来调整控件的尺寸,具体是通过调整app:layout_constraintDimensionRatio来实现,比如设置1:1,那么控件宽高就是1:1。

1.4.4、链条约束

链条约束用于在一组控件之间分配空间,或者说是控制一组空间的水平或者垂直布局。要实现这样的功能需要先用相对位置约束将几个控件链接在一起,然后使用layout_constraintHorizontal_chainStyle、layout_constraintVertical_chainStyle来控制布局方式:

  • spread:均匀分布
  • spread_inside:两端控件固定,中间控件均匀分布
  • packed:控件紧密排列
<?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"><Buttonandroid:id="@+id/button0"android:layout_width="100dp"android:layout_height="200dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintLeft_toLeftOf="parent"android:text="Button 0" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintTop_toBottomOf="@id/button0"app:layout_constraintLeft_toRightOf="@id/button0"android:text="Button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_bias="0.4"android:text="Button 2"/><Buttonandroid:id="@+id/button_chain1"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toLeftOf="@id/button_chain2"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_chainStyle="spread_inside"android:text="Button 1" /><Buttonandroid:id="@+id/button_chain2"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toRightOf="@id/button_chain1"app:layout_constraintRight_toLeftOf="@id/button_chain3"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_chainStyle="spread"android:text="Button 2" /><Buttonandroid:id="@+id/button_chain3"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toRightOf="@id/button_chain2"app:layout_constraintRight_toRightOf="parent"app:layout_constraintBottom_toBottomOf="parent"android:text="Button 3" /><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintDimensionRatio="1:1"android:text="This is a text view" /></androidx.constraintlayout.widget.ConstraintLayout>

请添加图片描述

2、AndroidManifest

2.1、常见标签以及作用:

  • manifest:根标签,定义了整个应用的基本信息,像包名和兼容性要求等
  • application:描述应用的全局信息,比如图标、名称、主题以及包含的组件等,一个app只能包含一个
  • activity:声明一个用户界面
    • intent-filter:描述 Activity 能够响应的 Intent
  • service:声明一个service组件
  • receiver:声明应用中的一个 BroadcastReceiver 组件,BroadcastReceiver 能让应用对系统或其他应用发出的广播消息做出响应。
  • provider:声明应用中的一个 ContentProvider 组件,ContentProvider 可以让应用共享数据给其他应用
  • uses-permission:放在application标签外,属于应用整体需求,用于声明应用所需的系统权限

2.2、activity标签

用于声明应用中的一个 Activity 组件,它可以包含多个子标签:

  • intent-filter:描述Activity可以响应的Intent,一个Activity可以有多个intent-filter
  • permission:指定启动该activity需要的权限
  • screenOrientation:activity标签属性,对activity的屏幕方向进行控制
    • portrait:强制竖屏
    • landscape:强制横屏
    • sensor:根据设备的传感器自动调整屏幕方向
  • launchMode:activity标签属性,用于定义 Activity 的启动模式
    • standard:默认的启动模式,每次启动 Activity 都会创建一个新的实例。
    • singleTop:如果 Activity 已经位于任务栈的栈顶,再次启动时不会创建新的实例
    • singleTask:系统会为该 Activity 创建一个新的任务栈,并将其置于栈底,若该 Activity 已经存在于某个任务栈中,会将其之上的所有 Activity 出栈
    • singleInstance:该 Activity 会独占一个任务栈,并且在系统中只有一个实例

2.3、intent-filter的过滤机制

intent-filter中可能有三个子标签:

  • action:用于指定组件能够处理的操作类型,一个intent-filter可以包含多个action标签,只要匹配其中一个就满足action的过滤条件
    • android.intent.action.MAIN
    • android.intent.action.VIEW
    • android.intent.action.SEND
    • android.intent.action.EDIT
    • android.intent.action.DIAL
  • category:用于定义组件的类别,大多数隐式 Intent 都会默认包含这个类别,一个 intent-filter 可以包含多个 标签,Intent 必须包含 intent-filter 中定义的所有类别,才满足 category 过滤条件。
    • android.intent.category.DEFAULT
    • android.intent.category.LAUNCHER
    • android.intent.category.BROWSABLE
    • android.intent.category.APP_BROWSER
  • data:用于指定组件可以处理的数据类型,包括数据的 URI 格式和 MIME 类型,同样只要满足一个就满足过滤条件。

2.4、screenOrientation

该属性指定横屏或者竖屏启动,有以下影响:

对布局的影响:系统会依据 screenOrientation 属性和设备的实际方向,来加载对应的布局文件。通常,竖屏布局文件存于 res/layout 目录下,而横屏布局文件存于 res/layout-land 目录下。

对 Activity 生命周期的影响:屏幕方向改变时,Activity 可能会经历销毁和重建的过程,通过设置screenOrientation,即使用户旋转设备,Activity 也不会因为方向改变而重建。

当把 screenOrientation 属性固定为 portrait,而屏幕物理方向变为 landscape 时,实际上就是将竖屏的布局以横屏的形式展现出来。固定screenOrientation之后,layout不会再切换,所以Activity不会销毁,引发的问题可能是layout被拉伸或者裁剪。

3、Activity

3.1、Activity的声明周期

Android声明周期可以分出三个阶段:

  • 完整生命周期(Entire Lifetime):从 onCreate开始,到 onDestroy结束。onCreate开始进行初始化,加载布局、初始化视图等;onDestroy结束释放所有的资源
  • 可见生命周期(Visible Lifetime):从 onStart开始,到 onStop结束。这个阶段Activity对用户是可见的。onStart会在 Activity变得可见时被调用,onStop则在 Activity不再可见时被调用。
  • 前台生命周期(Foreground Lifetime):从 onResume开始,到 onPause结束。此阶段用户可以与Activity交互,onResume在Activity即将与用户交互时被调用,onPause则在 Activity 即将失去焦点但仍可见时被调用。

生命周期方法详细说明:

  • onCreate:在 Activity 首次创建时调用,是 Activity 生命周期的起始点。在此方法中,一般会执行一些初始化操作,例如设置布局文件、初始化变量等
  • onStart:当 Activity 变为可见时调用,此时 Activity 已经被创建,但还未出现在前台
  • onResume:Activity 进入前台并开始与用户交互时调用,常用于恢复在 onPause中暂停的操作,如启动动画、开始播放音频等
  • onPause:当 Activity 失去焦点但仍可见时调用,通常用于暂停一些需要及时停止的操作,如暂停动画、停止音频播放等,同时保存一些临时数据
  • onStop:Activity 不再可见时调用,此时 Activity 可能被新的 Activity 完全覆盖,或者 Activity 即将被销毁,可以在此方法中释放一些占用资源较多的对象
  • onDestroy:Activity 被销毁前调用,是 Activity 生命周期的最后一个方法,通常用于进行一些最终的清理工作,如关闭数据库连接、取消未完成的任务等
  • onRestart:当 Activity 从停止状态重新启动时调用,接着会调用 onStart方法

常见场景:

  • 首次启动 Activity:依次调用 onCreate() -> onStart() -> onResume()。
  • Activity 被其他 Activity 部分覆盖或弹出对话框:调用 onPause()。
  • Activity 被其他 Activity 完全覆盖:调用 onPause() -> onStop()。
  • Activity 从停止状态恢复:调用 onRestart() -> onStart() -> onResume()。
  • 用户按下返回键退出 Activity:调用 onPause() -> onStop() -> onDestroy()

3.2、Intent

Intent用于在不同组件之间传递信息,可以启动Activity、Service,也可以发送广播触发BroadcastReceiver。通过调用putExtra方法,可以向Intent中传递多种类型的数据。

Intent分为显示和隐式两种:

  • 显示:明确指定要启动的组件类名,一般在应用内部启动组件
// 启动 MainActivity
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
  • 隐式:不指定具体组件,而是通过action、data、category让系统寻找,常用于调用系统功能或者和其他应用交互。

startActivity有三个作用:启动新的Activity、传递数据、调用系统组件或其他应用的 Activity。

3.3、Intent

使用putExtra可以向Intent封装一些基本数据类型,如果要封装复杂数据类型,需要先将该数据类型进行序列化(实现Serializable或者Parcelable)。常用方法:

  • putExtra:封装数据
  • getIntent:获取Intent
  • getStringExtra:获取指定类型,指定键值的数据
  • getIntExtra
  • getBooleanExtra
  • getSerializableExtra
  • getExtras:获取bundle

3.4、Activity 的状态保存与恢复

  • onSaveInstanceState () 方法:当 Activity 由于某些原因(如屏幕旋转、系统内存不足等)即将被销毁时,系统会调用 onSaveInstanceState () 方法,在该方法中可以将 Activity 的重要状态数据保存到 Bundle 中。
  • onRestoreInstanceState () 方法:在 Activity 重新创建后,可以通过 onRestoreInstanceState () 方法从 Bundle 中恢复之前保存的状态数据。需要注意的是,onRestoreInstanceState () 方法只有在 Activity 是由于异常情况而重新创建时才会被调用,而在正常的启动过程中不会被调用。

4、Service

Service是Android中用于后台执行长时间运行操作,且不提供用户界面的组件。Service分为两种类型:启动服务(Started Service)和绑定服务(Bound Service)。

4.1、Service 的生命周期

4.1.1、启动服务

启动服务通过StartService启动,会在后台一直运行,直到被停止。

  • onCreate:服务第一次被创建时调用此方法,如果服务已经处于运行状态,再次调用StartService不会触发onCreate。onCreate主要负责初始化。
  • onStartCommand(Intent intent, int flags, int startId):每次调用startService启动服务都会调用onStartCommand方法。onStartCommand主要用于执行具体的后台任务。
    • 参数说明:
      • intent
      • flags:启动服务的额外信息,可能的值有 START_FLAG_REDELIVERY、START_FLAG_RETRY 等
      • startId:表示此次启动请求的唯一ID
    • 返回值:该方法需要返回一个整数,指示服务因内存不足被杀死之后的动作:
      • START_STICKY:重新重建服务并调用onStartCommand,但是不传递之前的Intent
      • START_NOT_STICKY:不重新创建服务
      • START_REDELIVER_INTENT:重新创建服务并且传递之前的Intent
  • onDestory:服务不再使用且将被销毁时调用此方法,可以通过stopService或者服务内部调用stopSelf来触发服务的销毁。onDestory主要用于释放资源。

onCreate 只会被执行一次,意味着 Service 在首次创建后,后续可以被多次启动,但不会再次执行 onCreate 方法。当使用 startService() 多次启动同一个 Service 时,onStartCommand 方法会被多次调用,这样可以让 Service 多次执行特定的任务。

当所有的 Service 都停止后,再次调用 startService() 方法启动该 Service 时,onCreate() 方法会再次执行。

在 Android 中,Service 的 onCreate 方法只被调用一次,在该方法中初始化的变量对于该 Service 实例来说是全局变量,这些变量在该 Service 实例的各个方法之间是共享的。

4.1.2、绑定服务

绑定服务运行其他组件与服务进行交互。

  • onCreate:当服务第一次被创建时调用。服务通过bindService启动,只要没有服务实例,就会调用onCreate方法。
  • onBind(Intent intent):当客户端调用bindService方法绑定服务时,系统调用onBind,该方法返回一个IBinder对象,客户端通过IBinder对象与服务进行通信。
  • onUnbind(Intent intent):当所有客户端都调用 unbindService() 方法解除与服务的绑定后,系统会调用 onUnbind() 方法。该方法返回一个bool值,如果是false,表示有新的客户端再次绑定服务时,不会调用onRebind;如果返回true,表示服务希望在后续有新客户端绑定时能够直接通过 onRebind 方法重新绑定,而不是重新走 onBind 流程,所以bind service不会自动执行onDestroy。
  • onRebind(Intent intent):当 onUnbind() 方法返回 true,并且有新的客户端再次绑定服务时,系统会调用 onRebind() 方法。(前提是服务仍然存活)
  • onDestroy:在所有客户端都解除绑定后,系统会销毁服务并调用 onDestroy() 方法。 onUnbind 返回 true 时,bind service 不会自动执行 onDestroy。

由于onBind方法通常只会在首次绑定时被调用一次,因此,多次调用 bindService 得到的 IBinder 对象通常是同一个。通过IBinder获取的服务对象一般来说也是同一个。

4.2、我理解的服务的本质

无论是通过 startService() 启动的服务,还是通过 bindService() 绑定的服务,本质上它们都只是普通的 Java 对象,并且默认情况下运行在应用的主线程中。在调用startService之后,我们可以看到onCreate以及onStartCommand打印的线程号是等于主线程号的。

另外,绑定服务和启动服务,它们都是继承于Service,只不过链接的方式不一样,系统自动调用的方法不一样,对于一个绑定服务,我们覆写onStartCommand方法也是可以当成启动服务来使用的。

为何使用 ServiceConnection 来获取 Binder 进而获取服务实例:

  • 启动绑定服务需要用到ServiceConnection,这是因为bindService是一个异步操作,调用此方法后,系统不会立即返回服务实例(服务可能要做促使话)。ServiceConnection会提供回调接口,在绑定成功后通知客户端。
  • ServiceConnection 还可以处理服务连接状态的变化,例如服务断开连接。
  • 跨进程通信支持

接下来是我想到的几个问题:

  • 调用 bindService 时,传入的 ServiceConnection 是不是不能是临时变量?
    • 如果将 ServiceConnection 作为临时变量,在方法执行完毕后,该变量可能会被垃圾回收机制回收。一旦发生这种情况,当服务连接状态发生变化时,系统就无法调用相应的回调方法,从而导致无法正确处理服务连接状态的变化。
  • 多次调用 bindService,为什么 onBind 和 onRebind 不会被重复调用,就像 startService 多次被调用时,onStartCommand 会多次被调用
  • 调用 unBindService 时是不是不能向 Service 传递信息?
    • 调用 unBindService 时,通常是用于解除客户端与服务之间的绑定关系,它本身并不用于向 Service 传递信息。
  • 调用者向 Service 传递信息是不是只能通过 IBinder 来实现?
    • 通过 IBinder 传递信息:调用IBinder自定义的方法
    • 通过 Intent 传递信息:调用bindService或者startService时通过Intent传递消息
    • 通过广播机制传递信息

bindService通常回合startService搭配使用,尤其是要去报Service长期存活,并且支持多次绑定的场景。

Service有以下几种使用方式:

  • 仅 bindService:临时通信(如前台界面与 Service 交互),Service对绑定共存亡
  • startService + bindService:长期后台任务,Service 解绑后仍存活,支持 onRebind
  • 仅 startService:无需双向通信的后台任务,无法直接调用 Service 方法

如何选择线程实现位置?

  • 单次后台任务:onStartCommand,直接启动Thread
  • 长期任务:onCreate + onStartCommand

耗时任务必须放在onStartCommand,或者Binder调用中。onCreatey用于初始化资源,onBind仅用于返回IBinder对象。

Service 可以通过广播或回调机制(给Service添加setCallback方法)将数据传递给 Activity。

4.3、IntentService(弃用)

之前实现的Service中,工作线程需要由我们自己实现。Android提供了一个更容易使用的版本IntentService,里面提供了简化后台任务处理的Service子类,适合执行异步、一次性、无需用户交互的耗时任务。

4.4、JobIntenService、WorkManager

4.5、跨进程访问 Service 的两种方式(暂不了解)

5、Broadcast Receiver

  • 广播:广播是一种在应用组件之前传递消息的机制,可用于系统和应用、应用和应用以及应用内部组件之间的通信。
  • 广播接收器:监听特定广播
  • 广播类型:
    • 普通广播:所有注册接收器的组件都可以收到,无法截断
    • 有序广播:按优先级一次传递,前一个接收器可以截断并修改广播内容
    • 粘性广播:弃用
    • 本地广播:应用内部传播,安全性高

广播接收器的注册方式:

  • 静态注册:在AndroidManifest中注册,应用未启动也能接收到广播( Android 8.0 及更高版本中,系统对后台运行的静态广播接收器进行了限制,)
<receiver android:name=".MyBroadcastReceiver"><intent-filter><action android:name="com.example.MY_CUSTOM_BROADCAST" /></intent-filter>
</receiver>
  • 动态注册:代码中通过registerReceiver注册,可以在需要时注册和注销。
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.MY_CUSTOM_BROADCAST");
registerReceiver(receiver, filter);

广播接收器的实现:继承BroadcatReceiver类,重写onReceive方法,在onReceive中获取Intent处理广播携带的数据。

广播的发送:

  • 普通广播发送:
Intent intent = new Intent("com.example.MY_CUSTOM_BROADCAST");
sendBroadcast(intent);
  • 有序广播发送:
Intent intent = new Intent("com.example.MY_CUSTOM_BROADCAST");
sendOrderedBroadcast(intent, null);

6、Content Provider

相关文章:

简单记录一下Android四大组件

1、Android Layout 1.1、LinearLayout 线性布局&#xff0c;子控件按照水平或垂直的方向依次排列&#xff0c;排列方向通过属性android:orientation控制&#xff0c;horizontal为水平排列&#xff0c;vertical为垂直排列。对于同一水平线上的控件&#xff0c;可以调整它的lay…...

在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布

2025年4月11日&#xff0c;人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括&#xff1a;数据源方面&#xff0c;Oracle数据源支持获取和查询物化视图&#xff1b;图表方面&#xff0c;在线地图支持天地图、腾讯地图&#xff1b;新增子弹图&…...

【图像处理基石】什么是通透感?

一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现&#xff0c;具体表现为&#xff1a; 色彩鲜明&#xff1a;颜色纯净且饱和度适中&#xff0c;无灰暗或浑浊感&#xff1b;层次分明&#xff1a;明暗过渡自然&#xff0c;光…...

猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新

前情提要 家里养了三只猫咪&#xff0c;其中一只布偶猫经常出入厕所。但因为平时忙于学业&#xff0c;没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关&#xff0c;频繁如厕可能是泌尿问题&#xff0c;停留过久也可能是便秘或不适。为了更科学地了解牠的如…...

NoSQL入门指南:Redis与MongoDB的Java实战

一、为什么需要NoSQL&#xff1f; 在传统SQL数据库中&#xff0c;数据必须严格遵循预定义的表结构&#xff0c;就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL&#xff08;Not Only SQL&#xff09;数据库则像一个灵活的储物间&#xff0c;允许存储各种类型的数据&#x…...

游戏引擎学习第223天

回顾 今天我们正在进行过场动画序列的制作&#xff0c;因此我想深入探讨这个部分。昨天&#xff0c;我们暂时停止了过场动画的制作&#xff0c;距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列&#xff0c;并把它们集中…...

【redis进阶二】分布式系统之主从复制结构(1)

目录 一 为什么要有分布式系统&#xff1f; 二 分布式系统涉及到的非常关键的问题&#xff1a;单点问题 三 学习部署主从结构的redis (1)创建一个目录 (2)进入目录拷贝两份原有redis (3)使用vim修改几个选项 (4)启动两个从节点服务器 (5)建立复制&#xff0c;要想配…...

(自用)若依生成左树右表

第一步&#xff1a; 在数据库创建树表和单表&#xff1a; SQL命令&#xff1a; 商品表 CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(255) , price DECIMAL(10, 2) , stock INT NOT NULL, category_id INT NOT NULL); 商品分类…...

VectorBT量化入门系列:第六章 VectorBT实战案例:机器学习预测策略

VectorBT量化入门系列&#xff1a;第六章 VectorBT实战案例&#xff1a;机器学习预测策略 本教程专为中高级开发者设计&#xff0c;系统讲解VectorBT技术在量化交易中的应用。通过结合Tushare数据源和TA-Lib技术指标&#xff0c;深度探索策略开发、回测优化与风险评估的核心方法…...

5G网络下客户端数据业务掉线频繁

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;客户端的日志&#xff0c;和界面在待机状态下&#xff08;即没有做通话等业务操作&#xff09;&#xff0c;会频繁提示“离线”。 主要先看有没有丢网&#xff0c;UL BLER有没有问题。确认没有问题。看到业务信道释…...

CPU(中央处理器)

一、CPU的定义与核心作用 CPU 是计算机的核心部件&#xff0c;负责 解释并执行指令、协调各硬件资源 以及 完成数据处理&#xff0c;其性能直接影响计算机的整体效率。 核心功能&#xff1a; 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…...

Java从入门到“放弃”(精通)之旅——程序逻辑控制④

Java从入门到“放弃”&#xff08;精通&#xff09;之旅&#x1f680;&#xff1a;程序逻辑的完美理解 一、开篇&#xff1a;程序员的"人生选择" 曾经的我&#xff0c;生活就像一段顺序执行的代码&#xff1a; System.out.println("早上8:00起床"); Syste…...

[Dify] 基于明道云实现金融业务中的Confirmation生成功能

在金融业务的日常流程中,交易记录的处理不仅涉及数据录入、流程审批,更重要的是其最终输出形式——交易确认函(Confirmation)。本文将介绍如何通过明道云的打印模板功能,快速、准确地生成符合业务需求的交易Confirmation,提升工作效率与合规性。 为什么需要Confirmation?…...

Qt安卓设备上怎么安装两个不同的Qt应用?

在安卓设备上安装两个不同的Qt应用时&#xff0c;需要确保这两个应用在安卓系统中被视为独立的应用程序。以下是详细的步骤和注意事项&#xff0c;帮助你实现这一目标&#xff1a; 一、修改应用的包名 安卓系统通过应用的包名&#xff08;package属性&#xff09;来区分不同的…...

Prompt工程提示词(1-6章)

White graces&#xff1a;个人主页 &#x1f439;今日诗词:怅望千秋一洒泪&#xff0c;萧条异代不同时&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; 目录 &#x1f680; 第…...

0基础 | 硬件滤波 C、RC、LC、π型

一、滤波概念 &#xff08;一&#xff09;滤波定义 滤波是将信号中特定波段频率滤除的操作&#xff0c;是抑制和防止干扰的重要措施。通过滤波器实现对特定频率成分的筛选&#xff0c;确保目标信号的纯净度&#xff0c;提升系统稳定性。 &#xff08;二&#xff09;滤波器分…...

C++ 编程指南34 - C++ 中 ABI 不兼容的典型情形

一:概述 ABI(Application Binary Interface)是二进制层面的接口规范。如果一个库的 ABI 发生了变化,那么基于旧 ABI 编译的代码可能在运行时与新库不兼容(即使接口名字都一样也不行)。那么在C++中编程中,哪些情形会导致ABI不兼容呢?下面逐一列举一下。 二:C++ 中 ABI…...

【动态规划】深入动态规划:背包问题

文章目录 前言01背包例题一、01背包二、分割等和子集三、目标和四、最后一块石头的重量|| 完全背包例题一、完全背包二、 零钱兑换三、零钱兑换||四、完全平方数 前言 什么是背包问题&#xff0c;怎么解决算法中的背包问题呢&#xff1f; 背包问题 (Knapsack problem) 是⼀种组…...

NVIDIA AI Aerial

NVIDIA AI Aerial 适用于无线研发的 NVIDIA AI Aerial 基础模组Aerial CUDA 加速 RANAerial Omniverse 数字孪生Aerial AI 无线电框架 用例构建商业 5G 网络加速 5G生成式 AI 和 5G 数据中心 加速 6G 研究基于云的工具 优势100% 软件定义通过部署在数字孪生中进行测试6G 标准化…...

计算机视觉6——相机基础

一、数字相机基本工作原理 &#xff08;一&#xff09;像素概念 数字相机生成二维图像&#xff0c;图像最小单元是像素。 每个像素对应三维世界中某个特定方向&#xff0c;像素值衡量某一时刻来自该方向的光照强度/颜色 &#xff0c;即相机度量每个像素的光照情况并保存到对…...

入门到精通,C语言十大经典程序

以下是十个经典的C语言程序示例&#xff0c;这些程序涵盖了从基础到稍复杂的应用场景&#xff0c;适合初学者和有一定基础的开发者学习和参考。 1. Hello, World! 这是每个初学者学习编程时的第一个程序&#xff0c;用于验证开发环境是否正确配置。 #include <stdio.h>…...

【毕设】Python构建基于TMDB电影推荐系统

个性化电影推荐系统 这是一个基于FastAPI开发的现代化电影推荐系统&#xff0c;结合了协同过滤和深度学习技术&#xff0c;为用户提供个性化的电影推荐服务。 主要功能 &#x1f3af; 个性化电影推荐&#x1f50d; 电影搜索与浏览⭐ 电影评分系统&#x1f49d; 收藏夹功能&a…...

嵌入式常见概念的介绍

目录 一、MCU、MPU、ARM &#xff08;一&#xff09;MCU&#xff08;微控制器&#xff09; &#xff08;二&#xff09;MPU&#xff08;微处理器&#xff09; &#xff08;三&#xff09;ARM&#xff08;架构&#xff09; 二、DSP &#xff08;一&#xff09;数字信号处理…...

富兴号:拨云见日,打造普洱品质典范

在高端普洱茶市场的混沌格局中&#xff0c;价格与品质的天平严重失衡&#xff0c;消费者往往深陷 “高价却难觅好茶” 的困境。而新兴品牌富兴号强势崛起&#xff0c;奋力冲破这一迷局&#xff0c;致力于重塑 “号级茶” 的卓越品质&#xff0c;为茶叶赋予珍贵的品鉴与收藏价值…...

【WORD】批量将doc转为docx

具体步骤进行&#xff1a; 打开Word文档&#xff0c;按下AltF11快捷键&#xff0c;打开VBA编辑器。在VBA编辑器中&#xff0c;左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目&#xff08;通常以文档名称命名&#xff09;&#xf…...

Linux内存管理架构(1)

0.内存空间架构 1.用户空间 在 Linux 系统中&#xff0c;应用程序通过 malloc() 申请内存&#xff0c;并通过 free() 释放内存时&#xff0c;底层的内存管理是由 glibc&#xff08;GNU C Library&#xff09;中的内存分配器实现的。glibc 的内存分配器负责与操作系统的内核交互…...

Ubuntu 各个常见长期支持历史版本与代号

文章目录 1. Ubuntu 历史版本与代号2. 查看当前系统版本 在 Ubuntu 操作系统里&#xff0c;每个版本都有一个别具特色的名字。该名字由一个形容词与一个动物名称构成&#xff0c;且形容词和动物名称的首字母是一样的。例如 “Warty Warthog&#xff08;长疣的疣猪&#xff09;”…...

信息安全管理与评估2021年国赛正式卷答案截图以及十套国赛卷

2021年全国职业院校技能大赛高职组 “信息安全管理与评估”赛项 任务书1 赛项时间 共计X小时。 赛项信息 赛项内容 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 平台搭建与安全设备配置防护 任务1 网络平台搭建 任务2 网络安全设备配置与防护 第二…...

在线上定位1G日志文件中的异常信息时,我这样做合适吗

1G级线上日志文件 的异常定位系统性方案 一、快速定位流程 import datetime import randomdef generate_springboot_log(file_name, file_size_gb):# 模拟Spring Boot日志内容log_levels ["INFO", "DEBUG", "WARNING", "ERROR"]cla…...

Transformer模型中的两种掩码

模型训练通常使用 批处理batch来提升训练效率。而实际中Transformer的输入序列&#xff08;如句子、文本片段&#xff09;长度往往不一致。为了让这些样本可以组成一个统一的形状 [B, T] 的张量给GPU进行并行计算提高效率&#xff0c;需要将较短的序列填充&#xff08;pad&…...

FastAPI-MPC正式发布,新的AI敏捷开发利器

FastAPI-MCP发布&#xff1a;零配置构建微服务控制平台的革命性实践 引言 在微服务架构日益复杂的今天&#xff0c;如何快速实现API接口的标准化管理与可视化控制成为开发者面临的核心挑战。近日&#xff0c;FastAPI-MCP工具的发布引发了技术社区广泛关注&#xff0c;其宣称能…...

Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!

全文目录&#xff1a; 开篇语前言一、责任链模式概述责任链模式的组成部分&#xff1a; 二、责任链模式的核心优势三、使用责任链模式解耦复杂接口1. 定义 Handler 接口2. 实现具体的 Handler3. 创建订单对象4. 在 Spring Boot 中使用责任链模式5. 配置责任链6. 客户端调用 四、…...

学习笔记八——内存管理相关

&#x1f4d8; 目录 内存结构基础&#xff1a;栈、堆、数据段Rust 的内存管理机制&#xff08;对比 C/C、Java&#xff09;Drop&#xff1a;Rust 的自动清理机制Deref&#xff1a;为什么 *x 能访问结构体内部值Rc&#xff1a;多个变量“共享一个资源”怎么办&#xff1f;Weak&…...

Deepseek Bart模型相比Bert的优势

BART&#xff08;Bidirectional and Auto-Regressive Transformers&#xff09;与BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;虽然均基于Transformer架构&#xff0c;但在模型设计、任务适配性和应用场景上存在显著差异。以下是BART…...

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数&#xff08;决策树、逻辑回归、KNN、SVM&#xff09; 问题模板解题思路1. 导入必要的库2. 加载数据3. 划分训练集和测试集4. 数据预处理5. 定义算法及其参数6. 存储算法和对应指标7. 训练模型并计算指标8. 找…...

达梦数据库-学习-20-慢SQL优化之CTE等价改写

目录 一、环境信息 二、介绍 三、优化过程 1、原始SQL 2、源SQL执行时间 3、原始SQL执行计划 4、拆分问题 5、过滤性 6、统计信息收集 7、改写思路一 8、改写SQL一 9、改写SQL一的执行计划 10、改写思路二 11、改写SQL二 12、改写SQL二的执行计划 一、环境信息…...

软件生命周期模型:瀑布模型、螺旋模型、迭代模型、敏捷开发、增量模型、快速原型模型

目录 1.软件生命周期 2.软件生命周期模型 2.1瀑布模型 缺点【存在的问题】&#xff1a; 优点&#xff1a; 2.2 螺旋模型 特点&#xff1a; 2.3 迭代模型 优点&#xff1a; 2.4 敏捷开发 2.5 增量模型 增量模型一般和迭代模型一起使用&#xff1a; 2.6 快速原型模型…...

AI agents系列之全面介绍

随着大型语言模型(LLMs)的出现,人工智能(AI)取得了巨大的飞跃。这些强大的系统彻底改变了自然语言处理,但当它们与代理能力结合时,才真正释放出潜力——能够自主地推理、规划和行动。这就是LLM代理大显身手的地方,它们代表了我们与AI交互以及利用AI的方式的范式转变。 …...

Ubuntu 下通过 Docker 部署 WordPress 服务器

最近想恢复写私人博客的习惯&#xff0c;准备搭建一个wordpress。 在这篇博客中&#xff0c;我将记录如何在 Ubuntu 环境下通过 Docker 部署一个 WordPress 服务器。WordPress 是一个流行的内容管理系统&#xff08;CMS&#xff09;&#xff0c;它让用户能够轻松地创建和管理网…...

Elasticsearch生态

目录 Elasticsearch核心概念 Elasticsearch实现全文检索的原理 Elasticsearch打分规则 常用的查询语法 ES数据同步方案 Elasticsearch生态非常丰富&#xff0c;包含了一系列工具和功能&#xff0c;帮助用户处理、分析和可视化数据&#xff0c;Elastic Stack是其核心部分&a…...

idea配置spring MVC项目启动(maven配置完后)

springmvc项目在idea中配置启动总结&#xff0c;下面的内容是在maven配置好后进行的。 配置 Tomcat 服务器 添加 Tomcat 到 IDEA&#xff1a; File → Settings → Build, Execution, Deployment → Application Servers → 点击 → 选择 Tomcat Server。 指定 Tomcat 安装目…...

大模型微调数据集怎么搞?基于easydataset实现文档转换问答对json数据集!

微调的难点之一在与数据集。本文介绍一种将文档转换为问答数据集的方法&#xff0c;超级快&#xff01; 上图左侧是我的原文档&#xff0c;右侧是我基于文档生成的数据集。 原理是通过将文档片段发送给ollama本地模型&#xff0c;然后本地模型生成有关问题&#xff0c;并基于文…...

【排序算法】快速排序

目录 一、递归版本 1.1 hoare版本 问题1&#xff1a;为什么left 和 right指定的数据和key值相等时不能交换&#xff1f; 问题2&#xff1a;为什么跳出循环后right位置的值⼀定不⼤于key&#xff1f; 1.2 挖坑法 1.3 lomuto前后指针版本 二、快排优化 2.1 时间复杂度的计算 2.1.…...

爬虫:IP代理

什么是代理 代理服务器 代理服务器的作用 就是用来转发请求和响应 在爬虫中为何需要使用代理&#xff1f; 有些时候&#xff0c;需要对网站服务器发起高频的请求&#xff0c;网站的服务器会检测到这样的异常现象&#xff0c;则会讲请求对应机器的ip地址加入黑名单&#xff…...

JUC.atomic原子操作类原理分析

摘要 多线程场景下共享变量原子性操作除了可以使用Java自带的synchronized关键字以及AQS锁实现线程同步外&#xff0c;java.util.concurrent.atomic 包下提供了对基本类型封装类(AtomicBoolean|AtomicLong|AtomicReference|AtomicBoolean) 以及对应的数组封装。对于已有的包含…...

【XCP实战】AUTOSAR架构下XCP从0到1开发配置实践

目录 前言 正文 1.CAN功能开发 1.1 DBC的制作及导入 1.2 CanTrcv模块配置 1.3 Can Controller模块配置 1.4 CanIf模块配置 2.XCP模块集成配置配置 2.1.XCP模块配置 2.2.XCP模块的Task Mapping 2.3.XCP模块的初始化 3.在链接文件中定义标定段 4.编写标定相关的测试…...

【STM32】STemWin库,使用template API

目录 CubeMX配置 工程文件配置 Keil配置 STemwin配置 GUIConf.c LCDConf.c 打点函数 修改屏幕分辨率 GUI_X.c 主函数 添加区域填充函数 移植过程中需要一些参考手册&#xff0c;如下 STemwin使用指南 emWin User Guide & Reference Manual CubeMX配置 参考驱…...

Web开发-JavaEE应用动态接口代理原生反序列化危险Invoke重写方法利用链

知识点&#xff1a; 1、安全开发-JavaEE-动态代理&序列化&反序列化 2、安全开发-JavaEE-readObject&toString方法 一、演示案例-WEB开发-JavaEE-动态代理 动态代理 代理模式Java当中最常用的设计模式之一。其特征是代理类与委托类有同样的接口&#xff0c;代理类…...

C语言中while的相关题目

一、题目引入 以下程序中,while循环的循环次数是多少次? 二、代码分析 首先要明确的一点 while循环是当循环条件为真 就会一直循环 不会停止 while中i是小于10的 说明i可以取到0 1 2 3 4 5 6 7 8 9 进入第一个if判断i小于1为真时执行continue i0是为真的 执行continue 后…...

在Ubuntu下交叉编译 Qt 应用程序(完整步骤)

1、下载交叉编译器下&#xff1a; st-example-image-qt wayland-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-snapshot.sh 通过网盘分享的文件&#xff1a;STM32项目 链接: https://pan.baidu.com/s/1hTvJT2r6czWCrKSuNEZCuw?pwdth7t 提取码: th7t --来自百度网盘超级…...