Android之 Activity活动详解
一 四大组件
1.1 Activity组件,它一个单独的窗口,程序流程都必须在Activity中运行。
1.2 service组件,用于在后台完成用户指定的操作。
1.3 content provider组件,会为所有的应用准备一个内容窗口,并且保留数据库、文件。
1.4 broadcast receiver组件,是程序之间传递信息时的一种机制,作用就是接收或者发送通知。
二 Activity简介
2.1 Activity是四大组件中用的最多的,是数据显示的载体,也是用户视觉显示和行为操控的界面。
2.2 一个程序包含一个或者多个Activity,Activity之间的跳转和数据通信依赖于Intent(意图)。
三 Activity的创建
3.1 Actvity是一个Java类,先创建一个Class,继承于Activity或者
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}
3.2 创建xml布局文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent">................... </FrameLayout>
3.3 在清单文件AndroidManifest.xml注册Activity组件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"><uses-permission android:name="android.permission.INTERNET" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
3.5 Intent启动组件
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
四 Context上下文
4.1 很多人刚接触Context不太理解是干什么用的,上下文又是什么意思。Context其实是一个程序运行的环境,在这个环境里面可以做四大组件的启动,页面的跳转,资源的访问。总结起来就是应用程序和系统之间的桥梁,应用程序访问系统各种资源的接口
4.2 Context种类也不止一种,虽然都可以去访问系统资源,但各自的生命周期不一样。可以细分为以下三类:Application,Activity,service

4.3 生命周期的对比
Application的生命周期是最长的,一般应用不杀死就会一直存在。
Activity和Service的生命周期比较短,所以内存泄漏大部分发生在这两种Context的引用上面
4.4 Context使用场景对比

五 Activity生命周期
5.1 生命周期图示

5.2 如下复写Activity的生命周期
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//当Activity第一次被创建的时候调用此方法.一般在此方法中进行控件的声明,添加事件等初始化工作.}@Overrideprotected void onStart() {super.onStart();//当Activity被显示到屏幕上的时候调用此方法.}@Overrideprotected void onResume() {super.onResume();//当此Activity能够被操作之前,也就是能够获得用户的焦点之前调用此方法.}@Overrideprotected void onRestart() {super.onRestart();//当Activity被停止后又被再次启动之前调用此方法.接着将调用onStart()方法.}@Overrideprotected void onPause() {super.onPause();//当第一个Activity通过Intent启动第二个Activity的时候,将调用第一个Activity的onPause()方法.然后调用第二个Activity的onCreate(),onStart(),onResume()方法,接着调用第一个Activity的onStop()方法.如果Activity重新获得焦点,则将调用onResume()方法;如果此Activity进入用户不可见状态,那么将调用onStop()方法}@Overrideprotected void onStop() {super.onStop();//当第一个Activity被第二个Activity完全覆盖,或者被销毁的时候回调用此方法.如果此Activity还会与用户进行交互,将调用onRestart方法();如果此Activity将被销毁,那么将调用onDestroy()方法.}@Overrideprotected void onDestroy() {super.onDestroy();//Activity被销毁之前调用此方法.或者是调用finish()方法结束Activity的时候调用此方法.可以在此方法中进行收尾工作,比如释放资源等.}
}
5.3 比如两个Activity,AActivity.java和BActivity.java
打开AActivity,生命周期如下:
AActivity onCreate() -> AActivity onStart() -> AActivity onStart()
从AActivity跳转BActivity,生命周期如下:
AActivity onPause() -> BActivity oncreate() -> BActivity onstart() -> BActivity onresume() -> AActivity onstop()
从BActivity返回AActivity,生命周期如下:
BActivity onPause() -> AActivity onRestart() -> AActivity onStart() -> AActivity onResume() -> BActivity onStop() -> BActivity onDestroy()
5.4 Activity启动模式
- standard:默认启动模式,每次激活activity时,都创建activity实例,并放入任务栈。
- singleTop: 如果某个Activity自己激活自己,即任务栈栈顶是该Activity,则不需要创建,其余情况都要创建Activity。
- singleTask:如果要激活的activity在任务栈中,则不需要创建,只需要把这个Activity放入栈顶,并把该Activity以上的Activity实例都出栈。
- singleInstance:只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。
设置启动模式两种方式:
静态设置:
<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activityandroid:name=".MainActivity"android:launchMode="standard"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name=".Activity2"android:launchMode="singleTop"/><activity android:name=".Activity3"android:launchMode="singleTask"/><activity android:name=".Activity4"android:launchMode="singleInstance"/>
</application>
动态设置:
//默认不设置,即standard
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);//FLAG_ACTIVITY_SINGLE_TOP,即singleTop
Intent intent2 = new Intent(this,Activity2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent2);//FLAG_ACTIVITY_CLEAR_TOP,即singleTask
Intent intent3 = new Intent(this,Activity3.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent3);//FLAG_ACTIVITY_NEW_TASK,即singleInstance
Intent intent4 = new Intent(this,Activity4.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent4);
六 Intent意图
6.1 前面说过Intent也非常重要,是连接组件的桥梁,用来启动activity, service和broadcast receiver和组件之间的通信,而Content Provider本身就是一种通信机制,不需要通过Intent。
6.2 Intent启动组件
- 使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
- 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
- 将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver
6.3 Intent的属性
- component(组件):目的组件,一般是类名完整路径(包名.类名)
- action(动作):用来表现意图的行动
- category(类别):用来表现动作的类别
- data(数据):表示与动作要操纵的数据
- type(数据类型):对于data范例的描写
- extras(扩展信息):扩展信息
- Flags(标志位):期望这个意图的运行模式
根据不同的属性设置,启动Activity分为显式和隐式:
- 显式即直接启动,明确指向一个Activity类组件。
- 隐式指间接启动,根据action,category,data等筛选查找到匹配的组件。
6.4 显式启动的三种方式:
方式一:直接启动
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
方式二:setComponent新建组件启动
Intent intent = new Intent();
intent.setComponent(new ComponentName(this, MainActivity.class);)
startActivity(intent);
方式三:setClassName设置全Activity全路径
Intent intent = new Intent();
intent.setClassName(this,"com.dinghe.schemetestmain.MainActivity");
startActivity(intent);
6.5 隐式启动设置Action:
方式一:设置Action
如调用系统程序,系统Action
Intent intent = new Intent();
拨打电话
intent.setAction(Intent.ACTION_CALL);
发送短信
intent.setAction(Intent.ACTION_SENDTO);
打开相机
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
//启动
startActivity(intent);
方式二:如自定义Action,在AndroidManifest.xml里面设置intent-filter的Action
<activityandroid:name=".ActionActivity"android:exported="true"><intent-filter><action android:name="com.dinghe.schemetest.customerAction"/><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>
Intent intent = new Intent();
intent.setAction(getPackageName()+".customerAction");
startActivity(intent);
方式三:设置action+data,打开网站:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
方式四:设置action+data+type,打开指定类型文件
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data = Uri.parse("file:///storage/sdcard0/test.mp3");
//设置data+type属性
intent.setDataAndType(data, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
startActivity(intent);
方式五:设置action+category+data+extra+flags
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("smsto:"+"10086"));
intent.putExtra("keyName","keyValue");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
注意: 如果自己定义的某个Action要通过隐式启动,在AndroidManifast.xml中必须加上 android.intent.category.DEFAULT,否则不起作用
七 Activity间通信
7.1 Activity传递数据要用到Intent.putExtra()方法,里面可以传递任意类型的数据,如下图所示传递基本类型,数组类型,字节类类型

集合类型,和Bundle类型

7.2 Intent传递数据
Intent intent = new Intent(this,MainActivity.class);
intent.putExtra("intKey",1);
intent.putExtra("StringKey","111");
startActivity(intent);
7.3 Bundle传递数据
Intent intent = new Intent(this,MainActivity.class);
Bundle bundle=new Bundle();
bundle.putInt("intKey",1);
bundle.putString("StringKey","111");
intent.putExtras(bundle);
startActivity(intent);
八 Activity启动流程
1. Launcher进程请求AMS
2. AMS发送创建应用进程请求
3. Zygote进程接受请求并孵化应用进程
4. 应用进程启动ActivityThread
5. 应用进程绑定到AMS
6. AMS发送启动Activity的请求
7. ActivityThread的Handler处理启动Activity的请求

九 Activity管理和回退
9.1 监听程序的后台和前台切换,如返回桌面和从桌面打开的状态。
利用Application.ActivityLifecycleCallbacks的方法,全局监听Activity的打开数量,数量0表示在后台,数量1表示前台
如下前后台监听的具体实现:
private Application.ActivityLifecycleCallbacks activityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {//打开的Activity数量统计private int activityStartCount = 0;@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityStarted(Activity activity) {activityStartCount++;//数值从0变到1说明是从后台切到前台if (activityStartCount == 1) {//从后台切到前台}}@Overridepublic void onActivityResumed(Activity activity) {}@Overridepublic void onActivityPaused(Activity activity) {}@Overridepublic void onActivityStopped(Activity activity) {activityStartCount--;//数值从1到0说明是从前台切到后台if (activityStartCount == 0) {//从前台切到后台}}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}@Overridepublic void onActivityDestroyed(Activity activity) {}
};
9.2 定义Activity回退栈,在Activity的onCreate里面添加进栈,可以在任意页面来结束指定页面或者全部页面
如下新建Activity栈的管理工具类:
public class ActivityUtil {public static Stack<Activity> activityStack = new Stack<Activity>();/*** 添加Activity到堆栈*/public static void addActivity(Activity activity) {activityStack.push(activity);}public static void removeActivity(Activity activity) {activityStack.remove(activity);}/*** 获取当前Activity(堆栈中最后一个压入的)*/public static Activity currentActivity() {return activityStack.lastElement();}/*** 结束当前Activity(堆栈中最后一个压入的)*/public static void finishCurrentActivity() {Activity activity = activityStack.pop();activity.finish();}/*** 结束指定的Activity*/public static void finishActivity(Activity activity) {if (activity != null) {
// activityStack.remove(activity);if (!activity.isFinishing()) {activity.finish();}}}/*** 结束指定的Activity*/public static void finishActivity(Activity activity,boolean isRemoveStack) {if (activity != null) {if (!activity.isFinishing()) {activity.finish();if(isRemoveStack){activityStack.remove(activity);}}}}public static void finishExcept(Class<?> cls) {for (Activity activity : activityStack) {if (!activity.getClass().equals(cls)) {finishActivity(activity);}}}/*** 结束指定类名的Activity*/public static void finishActivity(Class<?> cls) {for (Activity activity : activityStack) {if (activity.getClass().equals(cls)) {finishActivity(activity);}}}/*** 结束所有Activity*/public static void finishAllActivity() {for (Activity activity : activityStack) {if (activity != null) {activity.finish();}}activityStack.clear();}/*** 退出应用程序*/@SuppressLint("MissingPermission")public static void AppExit(Context context) {try {finishAllActivity();ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);manager.killBackgroundProcesses(context.getPackageName());System.exit(0);} catch (Exception e) {e.printStackTrace();}}
}
添加Activity到栈
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//添加Activity到栈ActivityUtil.addActivity(this);}
}
结束指定Activity
ActivityUtil.finishActivity(MainActivity.class);
十 两个app的通信和跳转
10.1 我们平时打开京东或者其它app,可以从应用内打开另一个应用,或者微信分享可以直接打微信的程序,还有网页H5可以跳转指定其它app页面,那这是怎样实现的呢。这就用到了应用间的跨进程跳转。
10.2 两个app,从一个app打开另一个app实现,想要打开另一个app,必须先知道app的包名,再根据包名显式和隐式的打开指定Activity。
10.3 显式方式跳转,跟正常Intent显式启动一样,指定包名和类型就可以打开
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName componentName = new ComponentName("com.dinghe.schemetest", "com.dinghe.schemetest.MainActivity");
intent.setComponent(componentName);
startActivity(intent);
10.4 网页H5跳转另一个app,通过intent-filter的data里面scheme实现。
scheme是一种页面内跳转协议,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;通过scheme协议,服务器可以定制化告诉App跳转到APP内部页面
实现步骤:
第一步:新建一个html网页test.html
<!DOCTYPE html>
<html><head><meta charset="UTF-8"></head><body><!-- <a href="[scheme]://[host]/[path]?[query]">启动应用程序</a> --><!-- scheme:判别启动的App --><!-- host:主机 没有也可以 --><!-- path:传值时必须的key 没有也可以 --><!-- query:获取值的Key和Value 没有也可以 --><a href="goods://test:8080/details?id=222">启动应用</a><br/></body>
</html>
第二步:新建目标协议页面SchemeActivity.java
public class SchemeActivity extends AppCompatActivity {private TextView tvContent;String id;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scheme);id=getIntent().getStringExtra("id");tvContent = (TextView) findViewById(R.id.tv_content);Intent intent = getIntent();Uri data = intent.getData(); //String action = intent.getAction();String scheme = intent.getScheme();Set<String> categories = intent.getCategories();StringBuilder stringBuilder=new StringBuilder();stringBuilder.append("data:").append(data).append("\n\n").append("action:").append(action).append("\n\n").append("categories:").append(categories).append("\n\n").append("scheme:").append(scheme).append("\n\n").append("id:").append(data.getQueryParameterNames()).append("\n\n").append("host:").append(data.getHost()).append("\n\n").append("path:").append(data.getPath()).append("\n\n").append("port:").append(data.getPort()).append("\n\n");tvContent.setText(stringBuilder);}
}
第三步:AndroidManifest.xml里面注册SchemeActivity的协议
<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"><activityandroid:name=".SchemeActivity"android:exported="true"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/><category android:name="android.intent.category.BROWSABLE"/><data android:scheme="goods"android:host="test"android:port="8080"android:path="/details"/></intent-filter></activity></application>
第四步:跳转该协议,点击h5网页里面的启动应用按钮,就能跳转另一个app了


10.6 利用三方SDK实现网页跳转其它app的方案,比如极光魔链平台运用这种短链可以实现该方案
如下流程

创建短链

相关文章:
Android之 Activity活动详解
一 四大组件 1.1 Activity组件,它一个单独的窗口,程序流程都必须在Activity中运行。 1.2 service组件,用于在后台完成用户指定的操作。 1.3 content provider组件,会为所有的应用准备一个内容窗口,并且保留数据库、…...
车载软件架构——闲聊几句AUTOSAR BSW(五)
我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 我们并不必要为了和谐,而时刻保持通情达理;我们需要具备的是,偶尔有肚量欣然承认在某些方面我们可能会有些不可理喻。该有主见的时候能掷地有声地镇得住场…...
APP图标尺寸规范一文了解清楚
在进行图标设计前,熟知手机 app 图标尺寸规范,能更好地去针对不同平台设计出更极致的图标。当前智能手机系统主要以 iOS 及 Android 为主,APP 图标是产品给用户的第一印象,图标视觉设计的美感与吸引力,与用户是否选择下…...
写给程序员Android Framework 开发,
前言 在 Android 开发者技能中,如果想进大厂,一般拥有较好的学历可能有优势一些。但是如果你靠硬实力也是有机会的,例如死磕Framework。Framework 知识广泛应用在Android各个领域中,重要性显而易见。 成为一名Android Framework…...
html实现一个一闪一闪的按钮,CSS实现一个一闪一闪的按钮,Css闪烁点标,css设置按钮层次感,css按钮美化,CSS按钮动画过渡,CSS按钮添加阴影
效果 动态 静态 实现 底部多加了几个过渡按钮 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><style>#app {margin: 2% auto;text-align: center;}.lay-btn-box {position: relative;display: …...
品优购项目学习记录04--列表页
文章目录 1.品优购项目列表页制作准备工作2.列表页header和nav修改2.1 秒杀logo的制作2.2 导航栏nav修改 3.列表页主体sk_container 1.品优购项目列表页制作准备工作 1.列表页面是新的页面,我们需要新建页面文件list.html 2.因为列表页的头部和底部基本一致&#x…...
script标签type值application/json,importmap和module
type(默认text/javascript) 该属性定义 script 元素包含或src引用的脚本语言。属性的值为 MIME 类型(媒体类型); 如果没有定义这个属性,脚本会被视作 JavaScript。 如果 MIME 类型不是 JavaScript 类型&a…...
基于ArcGIS实现陕西省1:250000比例尺地形图分幅和编号
1地形图的分幅与编号原理 我国1:1000000地形图的分幅采用国际1:1000000地图分幅标准,而其他比例尺地形图分幅以1:1000000比例尺地形图为基准进行分幅。每幅1:1000000地形图范围是经差6、纬差4;纬度60~ 76之间经差12、纬差4;纬度76~ 88之间经…...
校园安全,一键报警主机助力保障
校园安全,一键报警主机助力保障 随着社会发展和科技进步,校园安全问题日益受到重视。如何保障师生们的安全成为了学校一项重要任务。而校园可视一键报警主机就是一种非常有效的安保设备。 这种报警主机集合了视频监控、安全防范、数据处理等多个功能&a…...
RabbitMQ养成记 (7. 消息可靠性投递)
消息可靠性 什么是消息的可靠性呢?? 简单来说就是 你的消息发放给 exchange 这个过程中 有可能丢失或者失败 这时候需要一个回调机制来监控 发送结果 必要时还要返回信息。 rabbitmq 给我们提供了两种: 首先是生产者到exchange发送过程的监…...
SpringBoot配置连接两个或多个数据库
在Spring Boot应用中连接多个数据库或数据源可以使用多种方式,下面介绍两种常用的方法: 1、使用Spring Boot官方支持的多数据源配置 Spring Boot提供了官方支持的多数据源配置,可以简单地配置和管理多个数据源。 需要在application.proper…...
Python面试题汇总:高效备战技巧
Python面试题汇总:高效备战技巧 一、基础知识准备1 语言特点及优缺点2 数据类型3 运算符4 控制流程语句5 函数 二、面向对象编程1 面向对象编程基础2 类的创建及继承3 魔术方法4 多态5 设计模式 三、常用数据结构与算法1 字符串、列表、字典、集合字符串列表字典集合…...
如何区分比特率、波特率和频谱带宽?
01、什么是比特率和波特率? 宽带网络里面提及的千兆即1000Mbit/s,一般描述的是我们家网络端口每秒最大可接收0、1比特(bit)的数量,即每秒可接收1000x106个比特。显而易见,比特率越高,每秒传送的…...
sklearn中的特征工程(过滤法、嵌入法和包装法)
目录 编辑特征工程的第一步:理解业务 Filter过滤法 编辑方差过滤 编辑- 相关性过滤 - 卡方过滤 - F检验 - 互信息法 编辑嵌入法(Embedded) 包装法(Wrapper) 特征工程的第一步:理解业务 如…...
Linux C/C++并发编程实战(0)谈谈并发与并行
作为并发编程的第一讲,比较轻松,我们先来谈谈什么是并发和并行。 并发(Concurrency)是指一个处理器同时处理多个任务。 并行(Parallelism)是指多个处理器或者是多核的处理器同时处理多个不同的任务。 并发…...
2023年5月天津/南京/成都/深圳CDGA/CDGP数据治理认证报名
6月18日DAMA-CDGA/CDGP数据治理认证考试开放报名中! 考试开放地区:北京、上海、广州、深圳、长沙、呼和浩特、杭州、南京、济南、成都、西安。其他地区凑人数中… DAMA-CDGA/CDGP数据治理认证班进行中,报名从速! DAMA认证为数据管…...
【MySQL】MySQL批量插入测试数据的几种方式
文章目录 前言一、表二、使用函数生成设置允许创建函数产生随机字符串产生随机数字 三、创建存储过程插入角色表插入用户表 四、执行存储过程小结五、使用 Navicat自带的数据生成 前言 在开发过程中我们不管是用来测试性能还是在生产环境中页面展示好看一点, 又或者学习验证某…...
PowerShell install 一键部署virtualbox
VirtualBox 前言 VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public Licens…...
CTF权威指南 笔记 -第四章Linux安全机制-4.1-Stack Canaries
目录 Stack Canaries 简介 我们进行简单的例子 64 32 checksec Stack Canaries 是对抗栈溢出攻击的技术 SSP安全机制 Canary 的值 栈上的一个随机数 在程序启动时 随机生成并且保存在比返回地址更低值 栈溢出是从低地址向高地址进行溢出 如果攻击者要攻击 就一定要覆…...
KDZD400Q便携式三氯乙烯浓度检测仪
一、产品概述 检测仪用于快速检测多种气体浓度、温湿度测量并超标报警的场合。采用2.31寸高清彩屏实时显示,选用进口品牌的气体传感器,主要检测原理有:电化学、红外、催化燃烧、热导、PID 光离子等。 可以检测管道中或受限空间、大气环境中的…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
