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

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

文章目录

  • 使用Handler更新UI
  • Service
    • 基本特点
    • 启动方式
      • 非绑定式服务
        • 使用步骤
      • 绑定式服务
        • 步骤
    • 生命周期
      • 非绑定式
        • 启动阶段
        • 结束阶段
      • 绑定式
        • 启动阶段
        • 结束阶段
    • 前台Service
      • 使用步骤
      • 结束
        • 结束Service本身
        • 降级为普通Service
        • 降级为普通Service

使用Handler更新UI

  1. 主线程创建Handler对象,重写handlerMessage方法
  2. 子线程创建Message对象,使用Handler对象调用sendMessage方法发送消息,发到MessageQueue
  3. Looper一直尝试从MessageQueue中取出待处理消息,分发给Handler的handlerMessage方法中

image-20240806194619542

1722944819734

public class MainActivity extends AppCompatActivity {// 创建一个 Handler 实例,用于在主线程处理消息private Handler handler = new Handler(Looper.myLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);// 当接收到的消息的 what 属性为 1 时执行以下代码if (msg.what == 1) {// 获取消息中的数据并转换为字符串String data = (String) msg.obj;// 将 TextView 的文本设置为接收到的数据tv.setText(data);}}};private TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 设置活动的布局setContentView(R.layout.activity_main);// 获取布局文件中的 TextView 控件tv = findViewById(R.id.tv_response);// 获取布局文件中的 Button 控件Button button = findViewById(R.id.btn_send);// 为按钮设置点击事件监听器button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 创建一个新的 Message 对象Message message = new Message();// 设置消息的内容message.obj = "数据";// 设置消息的标识符message.what = 1;// 通过 handler 发送消息handler.sendMessage(message);}});}
}

Service

基本特点

  • 后台执行: Service 主要用于在后台执行一些长时间运行的操作,比如音乐播放、文件下载等,而不会影响用户界面的交互。
  • 没有界面: Service 不像 Activity 那样有界面。它运行在后台,通常没有用户界面。
  • 主线程: Service 运行在主线程中,因此在 Service 中执行耗时操作(如网络请求或文件操作)会阻塞主线程,可能会导致应用无响应。为了避免这种情况,通常需要使用异步机制,如 AsyncTaskHandlerExecutorService 等。

启动方式

非绑定式服务

(Started Service)

  • 启动方式:通过 startService() 方法启动。
  • 生命周期:服务的生命周期与启动它的组件无关。服务一旦启动,即使启动它的组件被销毁,服务仍会继续在后台运行,直到它自己被停止(通过 stopSelf()stopService())。
  • 交互:启动的服务不能被组件直接调用其方法。如果需要与服务进行交互,需要通过广播、MessengerAIDL 等方式。
  • 用途:适用于需要在后台执行长时间操作的情况,例如,下载文件、播放音乐等。
使用步骤
  1. 定义服务

定义一个继承自 Service 的类,并实现它的生命周期方法。

public class MyService extends Service {@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();Log.d("MyService", "onCreate()");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d("MyService", "onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();Log.d("MyService", "onDestroy()");}
}
  1. AndroidManifest.xml 中声明服务

确保在你的 AndroidManifest.xml 文件中注册服务:

<service android:name=".MyBoundService" />
  1. 启动服务
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void startService(View view) {Intent intent = new Intent(this, MyService.class);startService(intent);}
}
  1. 关闭服务

  2. 由启动者(通常是Activity)调用 stopService 方法。

  3. 服务内部调用 stopSelf 方法。

  • 由启动者关闭服务

在Activity中,可以通过调用 stopService 来停止服务:

Intent intent = new Intent(this, MyService.class);
stopService(intent);
  • 服务内部关闭自己

服务可以在内部调用 stopSelf 方法来停止自己:

public class MyService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 某些逻辑操作完成后,停止服务stopSelf();return START_NOT_STICKY;}
}

绑定式服务

(Bound Service)

  • 启动方式:通过 bindService() 方法启动。
  • 生命周期:服务的生命周期与绑定它的组件(如 Activity)有关。绑定服务的存在时间是基于组件的生命周期,如果所有绑定它的组件都被销毁,服务也会被销毁。
  • 交互:允许组件与服务进行交互,组件可以通过 ServiceConnection 接口获取到服务的引用,从而调用服务中的方法。
  • 用途:适用于需要与服务进行长期交互的情况,例如,组件需要获取服务的数据或调用服务中的方法。
步骤
  1. 定义服务

定义一个继承自 ServiceMyBindService类,并实现 onBind() 方法以返回一个实现IBinder 接口的类的对象。这个 IBinder 对象将用于与客户端进行通信。我们定义一个MyBinder类继承自Binder类,Binder类实现了IBinder接口

public class MyBindService extends Service {private static final String TAG = "MyBindService";// 测试服务的方法public void testService() {Log.d(TAG, "服务的测试");}@Overridepublic void onCreate() {Log.d(TAG, "onCreate executed");super.onCreate();// 在服务创建时初始化一些资源}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand executed");// 这里可以处理服务启动时的逻辑return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {Log.d(TAG, "onDestroy executed");super.onDestroy();// 在服务销毁时释放资源}@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind executed");return new MyBinder(this);}@Overridepublic boolean onUnbind(Intent intent) {Log.d(TAG, "onUnbind executed");return super.onUnbind(intent);// 可以在这里处理服务解绑时的逻辑}// Binder类实现了IBinder接口public class MyBinder extends Binder {private final MyBindService mMyBindService;// 构造函数,用于初始化服务实例public MyBinder(MyBindService myBindService) {mMyBindService = myBindService;}// 提供一个方法来获取服务实例public MyBindService getService() {return mMyBindService;}// 测试Binder的方法public void test() {Log.d(TAG, "MyBinder测试");mMyBindService.testService();}}
}
  1. AndroidManifest.xml 中声明服务
<service android:name=".MyBoundService" />
  1. 绑定服务

在你的组件(如 Activity)中,通过 bindService() 方法绑定到服务。你需要实现 ServiceConnection 接口来处理与服务的连接状态。

public class MainActivity extends AppCompatActivity {// 定义一个MyBinder对象,用于绑定服务后与服务交互public MyBindService.MyBinder myBinder = null;// 定义一个ServiceConnection对象,用于管理服务的连接和断开private ServiceConnection coon = new ServiceConnection() {// 当服务成功连接时回调该方法@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// 将传入的IBinder对象转换为MyBindermyBinder = (MyBindService.MyBinder) service;// 调用MyBinder的test方法,测试服务功能myBinder.test();}// 当服务断开连接时回调该方法@Overridepublic void onServiceDisconnected(ComponentName name) {// 可以在这里处理服务断开时的逻辑}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}// 绑定服务的方法public void bindService(View view) {Intent intent = new Intent(this, MyBindService.class);bindService(intent, coon, BIND_AUTO_CREATE);}
}
  1. 解除绑定

通过 unbindService() 方法来完成解除绑定的操作

@Override
protected void onStop() {super.onStop();if (isBound) {unbindService(connection);isBound = false;}
}

服务的绑定和解除绑定的注意事项

  • 绑定后:一旦绑定成功,组件可以通过服务提供的方法进行交互。
  • 解除绑定后:如果没有其他组件绑定该服务,服务会被销毁(如果服务是绑定服务),并调用 onDestroy() 方法进行清理。
  • 线程处理:如果服务需要执行长时间运行的任务,最好在服务中使用后台线程或异步任务来避免阻塞主线程。

生命周期

Service 的生命周期主要包括以下几个阶段:

  • onCreate(): 当服务第一次被创建时调用。通常在这里进行服务初始化。
  • onStartCommand(Intent intent, int flags, int startId): 当服务被 startService() 方法启动时调用。在这个方法中可以处理服务的任务。返回的 int 值决定了服务被系统杀掉后如何重启。
  • onBind(Intent intent): 当 bindService() 方法被调用时触发。用于提供与 Service 的绑定接口。若 Service 不需要绑定,可以返回 null
  • onDestroy(): 当服务被销毁时调用。通常在这里进行清理工作。

非绑定式

启动阶段
  • onCreate()
    • 只会在服务首次创建时调用一次。适合在这里做一些一次性的初始化工作。
  • onStartCommand(Intent intent, int flags, int startId)
    • 每次调用 startService 时都会执行。可以在这里处理传入的 Intent。
结束阶段

启动者(Activity)调用 stopService 或服务内部调用 stopSelf

  • 当 Activity 调用 stopService(Intent intent) 或服务内部调用 stopSelf() 方法时,服务会停止并触发 onDestroy 方法。

  • onDestroy()

    • 服务销毁前的最后一个方法。适合在这里做一些资源释放的收尾工作。

      @Override
      public void onDestroy() {super.onDestroy();// 释放资源
      }
      

绑定式

启动阶段

**启动者(Activity)**调用 bindService(Intent intent, ServiceConnection conn, int flags)

  • onCreate()
    • 只会在服务首次创建时调用一次。适合在这里做一些一次性的初始化工作。
  • onBind(Intent intent)
    • 只会在首次绑定时执行一次。返回一个 IBinder 对象,供客户端与服务进行通信。
结束阶段

启动者(Activity)销毁或调用 unbindService 方法

  • 当 Activity 销毁或调用 unbindService(ServiceConnection conn) 方法时,会解除与服务的绑定。当没有绑定者时,服务会销毁。

  • onUnbind(Intent intent)

    • 解除绑定:当所有客户端都解除绑定时,会调用此方法。可以在这里处理一些解绑相关的逻辑。
  • onDestroy()

    • 销毁:服务销毁前的最后一个方法。适合在这里做一些资源释放的收尾工作。

注意事项

  • 服务绑定和解除绑定:确保在 Activity 的生命周期中正确绑定和解除绑定服务,以避免内存泄漏。
  • 资源释放:在 onDestroy 中释放所有资源,确保服务完全终止时不留下任何资源占用。

onCreate->onBind->onUnbind->onDestory

前台Service

前台服务 (Foreground Service) 是一种能够持续运行并与用户进行交互的服务。相比于后台服务,前台服务具有更高的优先级,通常不会被系统回收。

使用步骤

  1. 创建通知 (Notification)

前台服务必须显示一个通知来告知用户该服务正在运行。可以使用 NotificationCompat.Builder 来创建通知。

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("服务正在运行").setContentText("前台服务示例").setSmallIcon(R.drawable.ic_service_icon).build();
  1. 调用startForeground方法

在服务的 onCreateonStartCommand 方法中调用 startForeground(notificationId, notification) 方法,将服务提升到前台状态。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("服务正在运行").setContentText("前台服务示例").setSmallIcon(R.drawable.ic_service_icon).build();startForeground(1, notification);// 其他业务逻辑return START_STICKY;
}
  1. 申请权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

结束

  • 完全停止ServicestopServicestopSelf
  • 降级Service状态stopForeground(true) 将Service从前台状态退出并移除通知,但Service仍然在运行,只是优先级降低。
结束Service本身
  • 正常的结束Service方式:外部调用 stopService 方法或自身调用 stopSelf 方法。这两种方式都会完全停止Service。当Service结束后,所有与之相关的通知也会被移除。

示例:

// 通过外部调用
stopService(new Intent(context, MyService.class));// 通过Service自身调用
stopSelf();
降级为普通Service

退出Service的前台状态,降级为普通Service

  • 调用 stopForeground(true) 方法:这会将Service从前台状态退出,变成普通的后台Service。这样做会降低Service的优先级,在系统内存不足时可能会被回收销毁。参数 true 表示同时移除通知。

示例:

// 将Service退出前台状态,同时移除通知
stopForeground(true);

elf` 方法。这两种方式都会完全停止Service。当Service结束后,所有与之相关的通知也会被移除。

示例:

// 通过外部调用
stopService(new Intent(context, MyService.class));// 通过Service自身调用
stopSelf();
降级为普通Service

退出Service的前台状态,降级为普通Service

  • 调用 stopForeground(true) 方法:这会将Service从前台状态退出,变成普通的后台Service。这样做会降低Service的优先级,在系统内存不足时可能会被回收销毁。参数 true 表示同时移除通知。

示例:

// 将Service退出前台状态,同时移除通知
stopForeground(true);


感谢您的阅读
如有错误烦请指正


相关文章:

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

文章目录 使用Handler更新UIService基本特点启动方式非绑定式服务使用步骤 绑定式服务步骤 生命周期非绑定式启动阶段结束阶段 绑定式启动阶段结束阶段 前台Service使用步骤结束结束Service本身降级为普通Service降级为普通Service 使用Handler更新UI 主线程创建Handler对象&a…...

Python爬虫入门实战(详细步骤)

1. 技术选型 爬虫这个功能&#xff0c;我个人理解是什么语言都能写的&#xff0c;只要能正常发送 HTTP 请求&#xff0c;将响应回来的静态页面模版 HTML 上把我们所需要的数据提取出来就可以了&#xff0c;原理很简单&#xff0c;这个东西当然可以手动去统计收集&#xff0c;但…...

5、Linux : 网络相关

OSI七层网络模型 TCP/IP四层 概念模型 对应网络协议 应用层&#xff08;Application&#xff09; HTTP、TFTP, FTP, NFS, WAIS、 表示层&#xff08;Presentation&#xff09; 应用层 Telnet, Rlogin, SNMP, Gopher 会话层&#xff08;Session&#xff09; SMTP…...

Linux中针对文件权限的解析

1.文件权限详细解析&#xff1a; -rw-r--r--. 1 root root 114 4月 10 16:32 100.txt 1)-rw-r--r--. 总共11位 第一个“-”和最后一个“.”不用去管&#xff0c;剩下 rw- r-- r-- 属主 属组 其他人 u g o 第一个是“-”表示普通文件 第一个是“d”表示文件目录 …...

【0304】psql 执行“VACUUM FULL”命令的背后实现过程

1. 概述 在前面讲解Postgres内核中解析器相关(【0297】Postgres内核之 INSERT INTO 原始解析树 转 Query 树 (1))内容时,曾提到过,Postgres内核大致将用户下发的SQL语句分为三大类,这里的VACUUM FULL属于CMD_UTILITY; 因此直接调用utility.c(实用程序)中的对应函数。…...

Java常见面试题-11-MongoDb

文章目录 MongoDB 是什么&#xff1f;MongoDB 和关系型数据库 mysql 区别MongoDB 有 3 个数据库分别是什么&#xff1f;MongoDB 中的数据类型MongoDB 适用业务场景 MongoDB 是什么&#xff1f; mongodb 是属于文档型的非关系型数据库&#xff0c;是开源、高性能、高可用、可扩…...

PBLOCK

PBLOCK是附加到Vivado中分配给Pblocks的单元格的只读属性 设计套房。 Pblock是一组单元格&#xff0c;以及一个或多个指定 Pblock所包含的设备资源。在平面规划过程中使用了Pblocks 将其放置到组相关逻辑中&#xff0c;并将其分配到目标设备的某个区域。请参阅 Vivado设计套件用…...

电子纸打造智能、自动化、绿色的工作流程

电子纸打造智能、自动化、绿色的工作流程 RFID技术最早在1940年代问世&#xff0c;1980年开始商业化使用。直到现在RFID&#xff08;无线射频识别&#xff09;技术已经深入到我们生活的方方面面。特别是在工业生产、物流运输等领域&#xff0c;RFID技术发挥着越来越重要的作用…...

Redis 的6种回收策略(淘汰策略)详解

Redis 的6种回收策略&#xff08;淘汰策略&#xff09;详解 1、Redis的六种淘汰策略1. volatile-lru2. volatile-ttl3. volatile-random4. allkeys-lru5. allkeys-random6. no-eviction 2、使用策略规则 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&am…...

SQL注入sqli-labs-master关卡一

本文环境搭建使用的是小皮&#xff0c;靶机压缩包&#xff1a;通过百度网盘分享的文件&#xff1a;sqli-labs-php7-master.zip 链接&#xff1a;https://pan.baidu.com/s/1xBfsi2lyrA1QgUWycRsHeQ?pwdqwer 提取码&#xff1a;qwer 下载解压至phpstudy的WWW目录下即可。 第一…...

LeetCode面试题Day6|LeetCode238 除自身以外数组的乘积、LeetCode134 加油站

题目1&#xff1a; 指路&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;238 除自身以外数组的乘积 思路与分析&#xff1a; 除去自身元素求其他元素的乘积&#xff0c;或许第一反应会是数组元素积乘再除以遍历到的元素&#xff0c;定义一个结果数组再对应放结果值&…...

猫头虎分享:Python库 FastAPI 的简介、安装、用法详解入门教程

&#x1f42f; 猫头虎分享&#xff1a;Python库 FastAPI 的简介、安装、用法详解入门教程 &#x1f680; &#x1f4c4; 摘要 作为一名专注于Python和人工智能开发的技术博主&#xff0c;猫头虎经常在开发过程中遇到各种挑战。最近&#xff0c;有粉丝问到如何高效地构建API&a…...

python连接MySQL数据库使用pymysql

开头 经过这么一段时间的学生信息管理系统的摸爬滚打&#xff0c;不断的学习更新的知识&#xff0c;不断修改自己的认知&#xff0c;针对pymysql以及MySQL数据库的知识做个总结&#xff0c;以纪念我这段时间的学习。 目录 开头 pymysql的使用流程 1.导入pymysql的工具包 方…...

AI时代下的编程趋势:程序员如何提升核心竞争力

随着人工智能和机器学习技术的飞速发展&#xff0c;大型语言模型和AI生成代码&#xff08;AIGC&#xff09;工具如ChatGPT、Midjourney、Claude等层出不穷&#xff0c;AI辅助编程逐渐成为现实。在这一变革的浪潮中&#xff0c;程序员群体面临着前所未有的挑战和机遇。一些人担忧…...

C#:基本语法

写在前面 本人在实习过程需要用C#进行开发&#xff0c;但本人之前的技术栈是C方向&#xff0c;所以在菜鸟教程上速通了一下C#的基本语法&#xff0c;总的来说和C还是非常相似的。 1 关键字 using关键字&#xff1a;使用命名空间class&#xff1a;使用类 2 注释 /* 这个程序…...

Redisson 实现分布式锁

文章目录 Redisson 是什么Redisson 使用客户端模式单节点模式哨兵模式主从模式集群模式Spring Boot 整合 Redisson 中的锁Redisson 可重入锁Redisson 公平锁Redisson 联锁Redisson 读写锁Redisson Redlock Redisson 的看门狗机制RedLock 解决单体故障问题如何使用 RedLockMarti…...

VMware ESXi学习笔记

esxi网络模型&#xff1a; 物理网卡: 一般会有多个物理网卡&#xff0c;用于管理口和其他(vsan) 虚拟交换机&#xff1a;创建虚拟交换机时&#xff0c;会要求选择至少1个上行链路(物理网卡) 端口组&#xff1a;一般一个虚拟交换机会创建两个端口组&#xff0c;一个虚机使用&a…...

Python 函数(2)

2、函数 2.1、函数传递列表 将列表传递给函数后&#xff0c;函数就能直接访问其内容。 下列为一个实例&#xff1a;将一个名字列表传递给一个名为greet_users()的函数&#xff0c;这个函数将会向列表中的每一个元素执行相应的信息。 def greet_users(name):for name in name…...

c++文件的读写

平常我们在编完代码后&#xff0c;基本都是从键盘输入&#xff0c;从屏幕输出&#xff08;显示&#xff09;&#xff0c;但可不可以从其他地方输入输出呢&#xff1f; ………………………………………………………………………………………………………………… 其实可以&…...

春秋云境 | 文件上传 | CVE-2022-30887

目录 靶标介绍 开启靶场 上传一句话木马 蚁剑连接 找到 flag 靶标介绍 多语言药房管理系统 (MPMS) 是用 PHP 和 MySQL 开发的, 该软件的主要目的是在药房和客户之间提供一套接口&#xff0c;客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库&#xff0…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...