【Android】Service使用方法:本地服务 / 可通信服务 / 前台服务 / 远程服务(AIDL)

1 本地Service

这是最普通、最常用的后台服务Service。

1.1 使用步骤

  • 步骤1:新建子类继承Service类:需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法
  • 步骤2:构建用于启动Service的Intent对象
  • 步骤3:调用startService()启动Service、调用stopService()停止服务
  • 步骤4:在AndroidManifest.xml里注册Service

1.2 本地Service 实例Demo

步骤1:新建子类继承Service类

需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()

MyService.java

public class MyService extends Service {//启动Service之后,就可以在onCreate()或onStartCommand()方法里去执行一些具体的逻辑
//由于这里作Demo用,所以只打印一些语句@Overridepublic void onCreate() {super.onCreate();System.out.println("执行了onCreat()");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("执行了onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();System.out.println("执行了onDestory()");}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}
}

步骤2:在主布局文件设置两个Button分别用于启动和停止Service

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="scut.carson_ho.demo_service.MainActivity"><Buttonandroid:layout_centerInParent="true"android:id="@+id/startService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="启动服务" /><Buttonandroid:layout_centerInParent="true"android:layout_below="@+id/startService"android:id="@+id/stopService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止服务" />
</RelativeLayout>

步骤3:构建Intent对象,并调用startService()启动Service、stopService停止服务

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button startService;private Button stopService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);startService = (Button) findViewById(R.id.startService);stopService = (Button) findViewById(R.id.stopService);startService.setOnClickListener(this);startService.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {//点击启动Service Buttoncase R.id.startService://构建启动服务的Intent对象Intent startIntent = new Intent(this, MyService.class);//调用startService()方法-传入Intent对象,以此启动服务startService(startIntent);//点击停止Service Buttoncase R.id.stopService://构建停止服务的Intent对象Intent stopIntent = new Intent(this, MyService.class);//调用stopService()方法-传入Intent对象,以此停止服务stopService(stopIntent);}}
}

步骤4:在AndroidManifest.xml里注册Service

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="scut.carson_ho.demo_service"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>//注册Service服务<service android:name=".MyService"></service></application></manifest>

Androidmanifest里Service的常见属性说明

属性说明备注
android:nameService的类名
android:labelService的名字若不设置,默认为Service类名
android:iconService的图标
android:permission申明此Service的权限有提供了该权限的应用才能控制或连接此服务
android:process表示该服务是否在另一个进程中运行(远程服务)不设置默认为本地服务;remote则设置成远程服务
android:enabled系统默认启动 true:Service 将会默认被系统启动;不设置则默认为false
android:exported该服务是否能够被其他应用程序所控制或连接不设置默认此项为 false

1.3 测试结果

在这里插入图片描述

2 可通信的服务Service

上面介绍的Service是最基础的,但只能单机使用,即无法与Activity通信
接下来将在上面的基础用法上,增设“与Activity通信”的功能,即使用绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())

2.1 步骤1:新建子类继承Service类,并新建一个子类继承自Binder类、写入与Activity关联需要的方法、创建实例

public class MyService extends Service {private MyBinder mBinder = new MyBinder();@Overridepublic void onCreate() {super.onCreate();System.out.println("执行了onCreat()");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("执行了onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();System.out.println("执行了onDestory()");}@Nullable@Overridepublic IBinder onBind(Intent intent) {System.out.println("执行了onBind()");//返回实例return mBinder;}@Overridepublic boolean onUnbind(Intent intent) {System.out.println("执行了onUnbind()");return super.onUnbind(intent);}//新建一个子类继承自Binder类class MyBinder extends Binder {public void service_connect_Activity() {System.out.println("Service关联了Activity,并在Activity执行了Service的方法");}}
}

步骤2:在主布局文件再设置两个Button分别用于绑定和解绑Service

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="scut.carson_ho.demo_service.MainActivity"><Buttonandroid:layout_centerInParent="true"android:id="@+id/startService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="启动服务" /><Buttonandroid:layout_centerInParent="true"android:layout_below="@+id/startService"android:id="@+id/stopService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止服务" /><Buttonandroid:layout_centerInParent="true"android:layout_below="@id/stopService"android:id="@+id/bindService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="绑定服务" /><Buttonandroid:layout_centerInParent="true"android:layout_below="@id/bindService"android:id="@+id/unbindService"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="解绑服务"/>
</RelativeLayout>

步骤3:在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系

即实现了Activity指挥Service干什么Service就去干什么的功能

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button startService;private Button stopService;private Button bindService;private Button unbindService;private MyService.MyBinder myBinder;//创建ServiceConnection的匿名类private ServiceConnection connection = new ServiceConnection() {//重写onServiceConnected()方法和onServiceDisconnected()方法//在Activity与Service建立关联和解除关联的时候调用@Overridepublic void onServiceDisconnected(ComponentName name) {}//在Activity与Service解除关联的时候调用@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//实例化Service的内部类myBinder//通过向下转型得到了MyBinder的实例myBinder = (MyService.MyBinder) service;//在Activity调用Service类的方法myBinder.service_connect_Activity();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);startService = (Button) findViewById(R.id.startService);stopService = (Button) findViewById(R.id.stopService);startService.setOnClickListener(this);stopService.setOnClickListener(this);bindService = (Button) findViewById(R.id.bindService);unbindService = (Button) findViewById(R.id.unbindService);bindService.setOnClickListener(this);unbindService.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {//点击启动Servicecase R.id.startService://构建启动服务的Intent对象Intent startIntent = new Intent(this, MyService.class);//调用startService()方法-传入Intent对象,以此启动服务startService(startIntent);break;//点击停止Servicecase R.id.stopService://构建停止服务的Intent对象Intent stopIntent = new Intent(this, MyService.class);//调用stopService()方法-传入Intent对象,以此停止服务stopService(stopIntent);break;//点击绑定Servicecase R.id.bindService://构建绑定服务的Intent对象Intent bindIntent = new Intent(this, MyService.class);//调用bindService()方法,以此停止服务bindService(bindIntent,connection,BIND_AUTO_CREATE);//参数说明//第一个参数:Intent对象//第二个参数:上面创建的Serviceconnection实例//第三个参数:标志位//这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service//这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行break;//点击解绑Servicecase R.id.unbindService://调用unbindService()解绑服务//参数是上面创建的Serviceconnection实例unbindService(connection);break;default:break;}}
}

2.2 测试结果

在这里插入图片描述

3 前台Service

前台Service和后台Service(普通)最大的区别就在于:

  • 前台Service在下拉通知栏有显示通知,但后台Service没有;
  • 前台Service优先级较高,不会由于系统内存不足而被回收;后台Service优先级较低,当系统出现内存不足情况时,很有可能会被回收

用法很简单,只需要在原有的Service类对onCreate()方法进行稍微修改即可,如下:

@Overridepublic void onCreate() {super.onCreate();System.out.println("执行了onCreat()");//添加下列代码将后台Service变成前台Service//构建"点击通知后打开MainActivity"的Intent对象Intent notificationIntent = new Intent(this,MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);//新建Builer对象Notification.Builder builer = new Notification.Builder(this);builer.setContentTitle("前台服务通知的标题");//设置通知的标题builer.setContentText("前台服务通知的内容");//设置通知的内容builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标builer.setContentIntent(pendingIntent);//设置点击通知后的操作Notification notification = builer.getNotification();//将Builder对象转变成普通的notificationstartForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来}

运行后,当点击Start Service或Bind Service按钮,Service就会以前台Service的模式启动(通知栏上有通知)

4 远程Service

4.1 远程服务与本地服务的区别

  • 远程服务与本地服务最大的区别是:远程Service与调用者不在同一个进程里(即远程Service是运行在另外一个进程);而本地服务则是与调用者运行在同一个进程里
  • 二者区别的详细区别如下图:在这里插入图片描述

4.2 应用场景

多个应用程序共享同一个后台服务(远程服务)

即一个远程Service与多个应用程序的组件(四大组件)进行跨进程通信

在这里插入图片描述

4.3 具体使用

为了让远程Service与多个应用程序的组件(四大组件)进行跨进程通信(IPC),需要使用AIDL

  1. IPC:Inter-Process Communication,即跨进程通信
  2. AIDL:Android Interface Definition Language,即Android接口定义语言;用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能。

在多进程通信中,存在两个进程角色(以最简单的为例):服务器端和客户端

以下是两个进程角色的具体使用步骤:

服务器端(Service)

  • 步骤1:新建定义AIDL文件,并声明该服务需要向客户端提供的接口
  • 步骤2:在Service子类中实现AIDL中定义的接口方法,并定义生命周期的方法(onCreateonBind等)
  • 步骤3:在AndroidMainfest.xml中注册服务 & 声明为远程服务

客户端(Client)

  • 步骤1:拷贝服务端的AIDL文件到目录下
  • 步骤2:使用Stub.asInterface接口获取服务器的Binder,根据需要调用服务提供的接口方法
  • 步骤3:通过Intent指定服务端的服务名称和所在包,绑定远程Service

接下来,举一个具体实例来介绍远程Service的使用

4.4 具体实例

实例描述:客户端远程调用服务器端的远程Service

4.4.1 服务器端(Service)

新建一个服务器端的工程:Service - server

步骤1. 新建一个AIDL文件
在这里插入图片描述
步骤2. 在新建AIDL文件里定义Service需要与Activity进行通信的内容(方法),并进行编译(Make Project)

// 在新建的AIDL_Service1.aidl里声明需要与Activity进行通信的方法
package scut.carson_ho.demo_service;interface AIDL_Service1 {void AIDL_Service();
}
//AIDL中支持以下的数据类型
//1. 基本数据类型
//2. String 和CharSequence
//3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型;
//4. AIDL自动生成的接口(需要导入-import)
//5. 实现android.os.Parcelable 接口的类(需要导入-import)

编译:build——》Make Project

步骤3:在Service子类中实现AIDL中定义的接口方法,并定义生命周期的方法(onCreate、onBind等)

MyService.java

public class MyService extends Service {// 实例化AIDL的Stub类(Binder的子类)AIDL_Service1.Stub mBinder = new AIDL_Service1.Stub() {//重写接口里定义的方法@Overridepublic void AIDL_Service() throws RemoteException {System.out.println("客户端通过AIDL与远程后台成功通信");}};//重写与Service生命周期的相关方法@Overridepublic void onCreate() {super.onCreate();System.out.println("执行了onCreat()");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("执行了onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();System.out.println("执行了onDestory()");}@Nullable@Overridepublic IBinder onBind(Intent intent) {System.out.println("执行了onBind()");//在onBind()返回继承自Binder的Stub类型的Binder,非常重要return mBinder;}@Overridepublic boolean onUnbind(Intent intent) {System.out.println("执行了onUnbind()");return super.onUnbind(intent);}}

步骤4:在AndroidMainfest.xml中注册服务 & 声明为远程服务

<serviceandroid:name=".MyService"android:process=":remote"  //将本地服务设置成远程服务android:exported="true"      //设置可被其他进程调用>//该Service可以响应带有scut.carson_ho.service_server.AIDL_Service1这个action的Intent。//此处Intent的action必须写成“服务器端包名.aidl文件名”<intent-filter><action android:name="scut.carson_ho.service_server.AIDL_Service1"/></intent-filter></service>

至此,服务器端(远程Service)已经完成了。

4.4.2 客户端(Client)

新建一个客户端的工程:Service - Client

步骤1:将服务端的AIDL文件所在的包复制到客户端目录下(Project/app/src/main),并进行编译

注:记得要原封不动地复制!!什么都不要改!

在这里插入图片描述
步骤2:在主布局文件定义“绑定服务”的按钮

MainActivity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="scut.carson_ho.service_client.MainActivity"><Buttonandroid:layout_centerInParent="true"android:id="@+id/bind_service"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="绑定服务"/>
</RelativeLayout>

步骤3:在MainActivity.java里

使用Stub.asInterface接口获取服务器的Binder;
通过Intent指定服务端的服务名称和所在包,进行Service绑定;
根据需要调用服务提供的接口方法。

MainActivity.java

public class MainActivity extends AppCompatActivity {private Button bindService;//定义aidl接口变量private AIDL_Service1 mAIDL_Service;//创建ServiceConnection的匿名类private ServiceConnection connection = new ServiceConnection() {//重写onServiceConnected()方法和onServiceDisconnected()方法//在Activity与Service建立关联和解除关联的时候调用@Overridepublic void onServiceDisconnected(ComponentName name) {}//在Activity与Service建立关联时调用@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//使用AIDLService1.Stub.asInterface()方法获取服务器端返回的IBinder对象//将IBinder对象传换成了mAIDL_Service接口对象mAIDL_Service = AIDL_Service1.Stub.asInterface(service);try {//通过该对象调用在MyAIDLService.aidl文件中定义的接口方法,从而实现跨进程通信mAIDL_Service.AIDL_Service();} catch (RemoteException e) {e.printStackTrace();}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bindService = (Button) findViewById(R.id.bind_service);//设置绑定服务的按钮bindService.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//通过Intent指定服务端的服务名称和所在包,与远程Service进行绑定//参数与服务器端的action要一致,即"服务器包名.aidl接口文件名"Intent intent = new Intent("scut.carson_ho.service_server.AIDL_Service1");//Android5.0后无法只通过隐式Intent绑定远程Service//需要通过setPackage()方法指定包名intent.setPackage("scut.carson_ho.service_server");//绑定服务,传入intent和ServiceConnection对象bindService(intent, connection, Context.BIND_AUTO_CREATE);}});}}

4.4.3 测试结果

点击绑定服务按钮
在这里插入图片描述
从上面测试结果可以看出:

  • 打印的语句分别运行在不同进程(看语句前面的包名)
  • 客户端调用了服务端Service的方法

客户端和服务端进行了跨进程通信

5 使用场景

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QML学习 —— 34、视频媒体播放器(附源码)

效果 说明 您可以单独使用MediaPlayer播放音频内容(如音频),也可以将其与VideoOutput结合使用以渲染视频。VideoOutput项支持未转换、拉伸和均匀缩放的视频演示。有关拉伸均匀缩放演示文稿的描述,请参见fillMode属性描述。 播放可能出错问题 出现的问题:      DirectS…

Spring MVC练习(前后端分离开发实例)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:二十五弦弹夜月&#xff0c;不胜清怨却飞来&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

如何把大模型调教成派大星?

目录 主要内容模型图实验结果如何把大模型变成派大星&#xff1f;chatglm3-6B 数据集准备代码运行微调结果 文章声明&#xff1a;非广告&#xff0c;仅个人体验&#xff1a;参考文献&#xff1a;https://www.aspiringcode.com/content?id17197387451937&uid291a2ae1546b48…

国土安全部发布关键基础设施安全人工智能框架

美国国土安全部 (DHS) 发布建议&#xff0c;概述如何在关键基础设施中安全开发和部署人工智能 (AI)。 https://www.dhs.gov/news/2024/11/14/groundbreaking-framework-safe-and-secure-deployment-ai-critical-infrastructure 关键基础设施中人工智能的角色和职责框架 https:/…

QML TableView 实例演示 + 可能遇到的一些问题(Qt_6_5_3)

一、可能遇到的一些问题 Q1&#xff1a;如何禁用拖动&#xff1f; 在TableView下加一句代码即可&#xff1a; interactive: false 补充&#xff1a;这个属性并不专属于TableView&#xff0c;而是一个通用属性。很多Controls下的控件都可以使用&#xff0c;其主要作用就是控…

C基础上机题目51_55

51.字符数组x中存有任意一串字符&#xff1b;请编制函数&#xff0c;按给定的替代关系对数组x中的所有字符进行替代&#xff0c;仍存入数组x的对应的位置上&#xff0c;最后调用函数把结果x输出。 替代关系&#xff1a;f(p)p*11%256 (p是数组中某一个字符的ASCII值&#xff0c…

03-微服务搭建

1、搭建分布式基本环境 分布式组件 功能 SpringCloud Alibaba - Nacos 注册中心&#xff08;服务发现/注册&#xff09;、配置中心&#xff08;动态配置管理&#xff09; SpringCloud Alibaba - Sentinel 服务容错&#xff08;限流、降级、熔断&#xff09; SpringCloud …

Java八股(一)

目录 1.JVM、JRE、JDK之间的关系 2.static关键字作用&#xff08;通俗版&#xff09; 3.面向对象、面向过程 4.私有方法 5.Java代码执行与编译 6.IOC 1.JVM、JRE、JDK之间的关系 Java一次编写到处运行&#xff0c;可移植性好&#xff0c;保证这一点的就是iava虚拟机JVM …

Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64

yum install 报错: Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64 CentOS7的SCL源在2024年6月30日停止维护了。 当scl源里面默认使用了centos官方的地址&#xff0c;无法连接&#xff0c;需要替换为阿里云。 cd /etc/yum.repos.d/ 找到 CentOS-SCLo-scl.repo 和…

Vue前端开发-slot传参

slot 又称插槽&#xff0c;它是在子组件中为父组件提供的一个占位符&#xff0c;使用来表示&#xff0c;通过这个占位符&#xff0c;父组件可以向中填充任意的内容代码&#xff0c;这些代码将自动替换占位符的位置&#xff0c;从而轻松实现在父组件中控制子组件内容的需求。 作…

如何在 Ubuntu 22.04 上安装带有 Nginx 的 ELK Stack

今天我们来聊聊如何在 Ubuntu 22.04 服务器上安装 ELK Stack&#xff0c;并集成 Nginx 作为 Web 服务器&#xff0c;同时使用 Let’s Encrypt Certbot 进行 SSL 认证。ELK Stack&#xff0c;包括 Elasticsearch、Logstash 和 Kibana&#xff0c;是一套强大的工具&#xff0c;用…

快速理解微服务中Sentinel怎么实现限流

Sentinel是通过动态管理限流规则&#xff0c;根据定义的规则对请求进行限流控制。 一.实现步骤 1.定义资源&#xff1a;在Sentinel中&#xff0c;资源可以是URL、方法等&#xff0c;用于标识需要进行限流的请求&#xff1b;(在Sentinel中&#xff0c;需要我们去告诉Sentinel哪些…

基于单片机的智慧小区人脸识别门禁系统

本设计基于单片机的智慧小区人脸识别门禁系统。由STM32F103C8T6单片机核心板、显示模块、摄像头模块、舵机模块、按键模块和电源模块组成。可以通过摄像头模块对进入人员人脸数据进行采集&#xff0c;识别成功后&#xff0c;舵机模块动作&#xff0c;模拟门禁打开&#xff0c;门…

llama-factory 系列教程 (七),Qwen2.5-7B-Instruct 模型微调与vllm部署详细流程实战

文章目录 介绍llama-factory 安装装包下载模型 微调模型数据集训练模型 微调后的模型推理 介绍 时隔已久的 llama-factory 系列教程更新了。本篇文章是第七篇&#xff0c;之前的六篇&#xff0c;大家酌情选看即可。 因为llama-factory进行了更新&#xff0c;我前面几篇文章的实…

利用Docker容器技术部署发布web应用程序

Docker是什么&#xff1f; docker 是一个开源的应用容器引擎&#xff0c;可以帮助开发者打包应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化&#xff0c;容器是完全使用沙箱机制&#xff0c;相互之间不会有任何…

SpringCloud框架学习(第五部分:SpringCloud Alibaba入门和 nacos)

目录 十二、SpringCloud Alibaba入门简介 1. 基本介绍 2.作用 3.版本选型 十三、 SpringCloud Alibaba Nacos服务注册和配置中心 1.简介 2.各种注册中心比较 3.下载安装 4.Nacos Discovery服务注册中心 &#xff08;1&#xff09; 基于 Nacos 的服务提供者 &#xf…

Linux—进程概念学习-03

目录 Linux—进程学习—31.进程优先级1.1Linux中的进程优先级1.2修改进程优先级—top 2.进程的其他概念3.进程切换4.环境变量4.0环境变量的理解4.1环境变量的基本概念4.2添加环境变量—export4.3Linux中环境变量的由来4.4常见环境变量4.5和环境变量相关的命令4.6通过系统调用获…

信创改造 - TongRDS 替换 Redis

记得开放 6379 端口哦 1&#xff09;首先在服务器上安装好 TongRDS 2&#xff09;替换 redis 的 host&#xff0c;post&#xff0c;passwd 3&#xff09;TongRDS 兼容 jedis # 例如&#xff1a;更改原先 redis 中对应的 host&#xff0c;post&#xff0c;passwd 改成 TongRDS…

Python 爬虫入门教程:从零构建你的第一个网络爬虫

网络爬虫是一种自动化程序&#xff0c;用于从网站抓取数据。Python 凭借其丰富的库和简单的语法&#xff0c;是构建网络爬虫的理想语言。本文将带你从零开始学习 Python 爬虫的基本知识&#xff0c;并实现一个简单的爬虫项目。 1. 什么是网络爬虫&#xff1f; 网络爬虫&#x…

从0到1部署Tomcat和添加servlet(IDEA2024最新版详细教程)

本文不仅细化了每一个步骤&#xff0c;实现了从0到1部署Tomcat和添加servlet。还针对IDEA2024版和以前的版本在部署上的区别&#xff0c;做了详细介绍&#xff0c;尤其是add framework support部分。与此同时&#xff0c;针对控制台中文乱码问题&#xff0c;本文也给出了详细解…