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

Android LifecycleOwner 闪退,java 继承、多态特性!

在这里插入图片描述

1. 闪退

同意隐私政策后,启动进入游戏 Activity 闪退

getLifecycle NullPointerException 空指针异常

FATAL EXCEPTION: main
Process: com.primer.aa.gg, PID: 15722
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.primer.aa.gg/com.android.boot.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.Lifecycle com.primer.game.LifecycleManager.getLifecycle()' on a null object referenceat android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4529)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4822)at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:118)at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:153)at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:104)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:3078)at android.os.Handler.dispatchMessage(Handler.java:117)at android.os.Looper.loopOnce(Looper.java:210)at android.os.Looper.loop(Looper.java:302)at android.app.ActivityThread.main(ActivityThread.java:9668)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:601)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1062)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.Lifecycle com.primer.game.LifecycleManager.getLifecycle()' on a null object referenceat com.primer.unitybridge.UniWbActivity.getLifecycle(UniWbActivity.java:387)at androidx.activity.ComponentActivity.<init>(ComponentActivity.java:221)at androidx.fragment.app.FragmentActivity.<init>(FragmentActivity.java:103)at androidx.appcompat.app.AppCompatActivity.<init>(AppCompatActivity.java:94)at com.google.androidgamesdk.GameActivity.<init>(GameActivity.java:58)at com.unity3d.player.UnityPlayerGameActivity.<init>(UnityPlayerGameActivity.java:20)at com.unity3d.player.UnityPlayerActivity.<init>(UnityPlayerActivity.java:3)at com.primer.unitybridge.UniWbActivity.<init>(UniWbActivity.java:53)at com.android.boot.MainActivity.<init>(MainActivity.java:56)at java.lang.Class.newInstance(Native Method)at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)at android.app.Instrumentation.newActivity(Instrumentation.java:1392)at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4508)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4822) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:118) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:153) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:104) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:3078) at android.os.Handler.dispatchMessage(Handler.java:117) at android.os.Looper.loopOnce(Looper.java:210) at android.os.Looper.loop(Looper.java:302) at android.app.ActivityThread.main(ActivityThread.java:9668) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:601) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1062) 

2. 分析

2.1 源码追溯

继承关系

MainActivityUniWbActivityUnityPlayerGameActivityGameActivityAppCompatActivityFragmentActivityComponentActivityActivity

Activity 来源

  • MainActivity:游戏页面
  • UniWbActivity:游戏页面
  • UnityPlayerGameActivity:游戏页面
  • GameActivity:依赖 androidx.games:games-activity:3.0.5
  • AppCompatActivity:依赖 androidx.appcompat:appcompat:1.3.1
  • FragmentActivity:依赖 androidx.fragment:fragment:1.3.6
  • ComponentActivity:依赖 androidx.activity:activity:1.2.4
  • Activity:依赖 Android API 31

接口实现

  • UniWbActivity:实现接口 LifecycleOwner

    1. 重写 getLifecycle 方法(getLifecycle 里面初始化)
    2. getLifecycle 里面调用成员变量直接 new 的 LifecycleManager 【注:这里是闪退关键,下面使用例子说明】
  • ComponentActivity:实现接口 LifecycleOwner

  • Activity:实现接口 implements LifecycleOwner

详细看堆栈日志:
他是在类实例初始化init方法里面调用getLifecycle抛出异常

在这里插入图片描述

跟进源码到androidx.activity.ComponentActivity 结合堆栈 <init> 方案发现其构造函数调用了getLifecycle()

在这里插入图片描述

1、我们知道类的继承:实例化一个对象,先会执行父类的构造,再执行子类的构造方法

所以结合上面的类继承关系可知:

  • 先执行父类 ComponentActivity 构造方法(里面调用了 getLifecycle)
  • 再执行子类 UniWbActivity 构造方法

2、还知道类的多态:如果父类和子类都实现了同一个接口,并且在父类中调用了接口方法,实际执行的是子类重写的接口方法实现

所以综上可知:

  • 会执行 UniWbActivity 里面重写的 getLifecycle 方法

这样看堆栈就对得上了,执行 ComponentActivity.<init> 之后跳到UniWbActivity.getLifecycle执行重写方法

2.2 问题复现

为什么会空指针?无非就是对象未实例化就调用!

为什么没有执行实例化对象?我根据源码写 Demo 复现

源码是怎么样的

  • 父类和子类实现同一个接口
  • 父类在构造函数里,调用实现的方法
  • 子类 new 一个成员变量
  • 子类实现的方法里调用成员变量实例

根据上面步骤编码,实例化子类执行,问题复现,出现空指针异常!

在这里插入图片描述

//共同接口
public interface AnimalInterface {public void eat();
}
//父类
public class Parent implements AnimalInterface {static {System.out.println("父类:cinit 静态初始化方法");}Parent() {System.out.println("父类:init 初始化方法(构造方法)");eat();}@Overridepublic void eat() {System.out.println("父类:eat");}
}
//子类
public class Child extends Parent implements AnimalInterface {private Cat cat = new Cat();static {System.out.println("子类:cinit 静态初始化方法");}Child() {System.out.println("子类:init 初始化方法(构造方法)");}@Overridepublic void eat() {System.out.println("子类:eat");cat.eatFish();}
}
//成员对象
public class Cat {static {System.out.println("Cat:cinit 静态初始化方法");}Cat() {System.out.println("Cat:init 初始化方法(构造方法)");}public void eatFish() {System.out.println("成员变量:猫吃鱼");}
}
//运行代码
public interface Main {public static void main(String[] args) {new Child();}
}

2.3 继续思考

为什么子类里面的成员对象 Cat 没有执行 new 实例化?显然是代码执行顺序问题!

怎么验证是执行顺序问题呢?把子类里面//cat.eatFish();注释掉再运行看看输出什么

在这里插入图片描述

很容易看出:

  • 先是执行子类重写的 eat 方法
  • 再执行成员变量 cat 的初始化

所以导致空指针异常!

不难发现,其实就是代码执行顺序的问题

2.4 产生错觉

调整代码执行顺序,使成员变量 Cat 的初始化先于子类 eat 执行即可。

可以把成员变量成员变量 cat 实例化写到静态代码块里,

这样 Child 的静态代码块先执行实例化 cat 再调用 eat 方法不会产生空指针异常了

public class Child extends Parent implements AnimalInterface {private static Cat cat;static {System.out.println("子类:cinit 静态初始化方法");cat = = new Cat();}Child() {System.out.println("子类:init 初始化方法(构造方法)");}@Overridepublic void eat() {System.out.println("子类:eat");cat.eatFish();}
}

以为万事大吉就此结束

2.5 新的错误

谁知道操作应用进入后台时出现了新的崩溃

在这里插入图片描述

重新复盘了,我的代码时这样的:

  • AppCompatActivity 的父类 ComponentActivity 实现了 LifecycleOwner,并重写 getLifecycle 方法
  • 这里我使用静态的 LifecycleRegistry,并重写 getLifecycle
package com.example.javademo;import android.os.Bundle;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;public class MainActivity extends AppCompatActivity implements LifecycleOwner {private static LifecycleRegistry LIFECYCLE_REGISTRY;private static final LifecycleOwner LIFECYCLE_OWNER = new LifecycleOwner() {@NonNull@Overridepublic Lifecycle getLifecycle() {return LIFECYCLE_REGISTRY;}};private TestActivityLifeObserver testActivityLifeObserver = new TestActivityLifeObserver();static {//有问题的代码:onpause 执行闪退,LifecycleOwner 已被回收导致空指针LIFECYCLE_REGISTRY = new LifecycleRegistry(new LifecycleOwner() {@NonNull@Overridepublic Lifecycle getLifecycle() {return LIFECYCLE_REGISTRY;}});}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});getLifecycle().addObserver(testActivityLifeObserver);LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);}@Overrideprotected void onStart() {super.onStart();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_START);}@Overrideprotected void onResume() {super.onResume();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);}@Overrideprotected void onPause() {super.onPause();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);}@Overrideprotected void onStop() {super.onStop();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_STOP);}@Overrideprotected void onDestroy() {super.onDestroy();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);LIFECYCLE_REGISTRY.removeObserver(testActivityLifeObserver);}@NonNull@Overridepublic Lifecycle getLifecycle() {return LIFECYCLE_REGISTRY;}
}
package com.example.javademo;import android.util.Log;import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;public class TestActivityLife implements DefaultLifecycleObserver {private final String TAG = "ceshi";@Overridepublic void onCreate(@NonNull LifecycleOwner owner) {Log.d(TAG, "onCreate: TestActivityLife");}@Overridepublic void onStart(@NonNull LifecycleOwner owner) {Log.d(TAG, "onStart: TestActivityLife");}@Overridepublic void onResume(@NonNull LifecycleOwner owner) {Log.d(TAG, "onResume: TestActivityLife");}@Overridepublic void onPause(@NonNull LifecycleOwner owner) {Log.d(TAG, "onPause: TestActivityLife");}@Overridepublic void onStop(@NonNull LifecycleOwner owner) {Log.d(TAG, "onStop: TestActivityLife");}@Overridepublic void onDestroy(@NonNull LifecycleOwner owner) {Log.d(TAG, "onDestroy: TestActivityLife");}
}

定位源码是 lifecycleOwner.get() 为空

在这里插入图片描述

原来弱引用 lifecycleOwner 就是静态代码块 new 的那个内部类 LifecycleOwner,应该是被回收了导致的空指针,

所以如何确保这个对象不轻易被回收?

open class LifecycleRegistry private constructor(provider: LifecycleOwner,private val enforceMainThread: Boolean
) : Lifecycle() {private val lifecycleOwner: WeakReference<LifecycleOwner>init {// LifecycleOwner 就是lifecycleOwner = WeakReference(provider)}}

强引用、弱引用

  • 如果在静态代码块中使用弱引用保存内部类对象,一旦静态代码块执行完毕,就没有任何强引用指向该对象了。 在下一次垃圾回收时,该对象很可能被回收。 除非有其他强引用指向该对象
  • 对象被声明为 static 时,它属于类本身,而不是类的实例。 会一直存在于内存中,直到类被卸载,静态变量的生命周期与类的生命周期相同,可以理解为他是强引用,不易被回收

把 LifecycleRegistry 代码抽象出来时这样的:

	//弱引用,所以后面你应该回收private final WeakReference<LifecycleOwner> mLifecycleOwner;public LifecycleRegistry(@NonNull LifecycleOwner provider) {mLifecycleOwner = new WeakReference<>(provider);}

调整之后的代码,确保 obj 不易被回收

static Object obj = new Object();WeakReference<Object> staticWeakReference = new WeakReference<>(obj);
  • obj: 这是一个静态变量,直接指向 new Object() 创建的对象。这是一个强引用。
  • staticWeakReference: 这是一个静态变量,保存了一个指向 obj 指向的同一个对象的弱引用。

关键在于,obj 这个强引用仍然存在。即使你创建了一个弱引用 staticWeakReference,obj 仍然持有对对象的强引用,这会阻止垃圾回收器回收该对象

3. 解决

那么把 LifecycleOwner 也设置成一个静态对象不久可以了吗

package com.example.javademo;import android.os.Bundle;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;public class MainActivity extends AppCompatActivity implements LifecycleOwner {private static final LifecycleRegistry LIFECYCLE_REGISTRY;private static final LifecycleOwner LIFECYCLE_OWNER = new LifecycleOwner() {@NonNull@Overridepublic Lifecycle getLifecycle() {return LIFECYCLE_REGISTRY;}};private TestActivityLifeObserver testActivityLifeObserver = new TestActivityLifeObserver();static {//LIFECYCLE_OWNER 使用静态对象,避免被回收LIFECYCLE_REGISTRY = new LifecycleRegistry(LIFECYCLE_OWNER);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});getLifecycle().addObserver(testActivityLifeObserver);LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);}@Overrideprotected void onStart() {super.onStart();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_START);}@Overrideprotected void onResume() {super.onResume();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);}@Overrideprotected void onPause() {super.onPause();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);}@Overrideprotected void onStop() {super.onStop();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_STOP);}@Overrideprotected void onDestroy() {super.onDestroy();LIFECYCLE_REGISTRY.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);//最后别忘了移除观察者,避免内存泄露LIFECYCLE_REGISTRY.removeObserver(testActivityLifeObserver);}@NonNull@Overridepublic Lifecycle getLifecycle() {return LIFECYCLE_REGISTRY;}
}

相比随着 Android 的不断更新 Activity 变成了 ComponentActivity,内部已实现生命周期

LifecycleOwner,随着逐渐升级到新版本 androidx.activity:activity,相比不久的将来你也要适配吧!

除了上述处理当然也有其他方法处理,只是恰巧我接手的这个老项目就是这样的场景,也不想改动太多就这样吧 😄

相关文章:

Android LifecycleOwner 闪退,java 继承、多态特性!

1. 闪退 同意隐私政策后&#xff0c;启动进入游戏 Activity 闪退 getLifecycle NullPointerException 空指针异常 FATAL EXCEPTION: main Process: com.primer.aa.gg, PID: 15722 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.primer.aa.…...

feign Api接口中注解问题:not annotated with HTTP method type (ex. GET, POST)

Bug Description 在调用Feign api时&#xff0c;出现如下异常&#xff1a; java.lang.IllegalStateException: Method PayFeignSentinelApi#getPayByOrderNo(String) not annotated with HTTPReproduciton Steps 1.启动nacos-pay-provider服务&#xff0c;并启动nacos-pay-c…...

Swipe横滑与SwipeItem自定义横滑相互影响

背景 vue项目&#xff0c;H5页面&#xff0c;使用vant的组件库轮播组件<Swipe>&#xff0c;UI交互要求&#xff0c;在每个SwipeItem中有内容&#xff0c;可自横滑&#xff0c;查看列表内容 核心代码 <template><Swipeclass"my_swipe":autoplay&quo…...

[LeetCode]day16 242.有效的字母异位词

242. 有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的 字母异位词 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输入: s "rat"…...

基于SpringBoot养老院平台系统功能实现五

一、前言介绍&#xff1a; 1.1 项目摘要 随着全球人口老龄化的不断加剧&#xff0c;养老服务需求日益增长。特别是在中国&#xff0c;随着经济的快速发展和人民生活水平的提高&#xff0c;老年人口数量不断增加&#xff0c;对养老服务的质量和效率提出了更高的要求。传统的养…...

基于HTML5 Canvas 和 JavaScript 实现的烟花动画效果

以下是一个使用 HTML5 Canvas 和 JavaScript 实现的烟花动画效果代码盒子: <!DOCTYPE html> <html> <head><title>烟花效果...

【3分钟极速部署】在本地快速部署deepseek

第一步&#xff0c;找到网站&#xff0c;下载&#xff1a; 首先找到Ollama &#xff0c; 根据自己的电脑下载对应的版本 。 我个人用的是Windows 我就先尝试用Windows版本了 &#xff0c;文件不是很大&#xff0c;下载也比较的快 第二部就是安装了 &#xff1a; 安装完成后提示…...

Linux ftrace 内核跟踪入门

文章目录 ftrace介绍开启ftraceftrace使用ftrace跟踪指定内核函数ftrace跟踪指定pid ftrace原理ftrace与stracetrace-cmd 工具KernelShark参考 ftrace介绍 Ftrace is an internal tracer designed to help out developers and designers of systems to find what is going on i…...

深入理解 Rust 模块中的路径与公开性:绝对路径、相对路径和 `pub` 的应用

1. 路径的两种形式&#xff1a;绝对路径与相对路径 在 Rust 中&#xff0c;路径类似于文件系统中的目录路径&#xff0c;用来告诉编译器去哪里查找某个项。路径主要有两种形式&#xff1a; 绝对路径 绝对路径从 crate 的根开始。对于当前 crate 的代码&#xff0c;绝对路径以关…...

基于钉钉API的连接器实现:企业数据集成与自动化管理

文章目录 概要背景与需求钉钉API概述连接器实现小结 概要 在当今数字化时代&#xff0c;企业面临着海量数据的管理与整合挑战。钉钉作为国内广泛使用的办公协作平台&#xff0c;提供了丰富的API接口&#xff0c;支持企业进行数据集成与自动化管理。本文将介绍如何通过钉钉API实…...

[Day 16]螺旋遍历二维数组

今天我们看一下力扣上的这个题目&#xff1a;146.螺旋遍历二维数组 题目描述&#xff1a; 给定一个二维数组 array&#xff0c;请返回「螺旋遍历」该数组的结果。 螺旋遍历&#xff1a;从左上角开始&#xff0c;按照 向右、向下、向左、向上 的顺序 依次 提取元素&#xff0c…...

【教程】docker升级镜像

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 自动升级 手动升级 无论哪种方式&#xff0c;最重要的是一定要通过-v参数做数据的持久化&#xff01; 自动升级 使用watchtower&#xff0c;可…...

使用jmeter进行压力测试

使用jmeter进行压力测试 jmeter安装 官网安装包下载&#xff0c;选择二进制文件&#xff0c;解压。 tar -xzvf apache-jmeter-x.tgz依赖jdk安装。 yum install java-1.8.0-openjdk环境变量配置&#xff0c;修改/etc/profile文件&#xff0c;添加以下内容。 export JMETER/…...

链表和 list

一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点&#xff0c;然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性&#xff1b; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…...

【AI大模型】Ubuntu18.04安装deepseek-r1模型+服务器部署+内网访问

以下内容主要参考博文&#xff1a;DeepSeek火爆全网&#xff0c;官网宕机&#xff1f;本地部署一个随便玩「LLM探索」 - 程序设计实验室 - 博客园 安装 ollama Download Ollama on Linux curl -fsSL https://ollama.com/install.sh | sh 配置 ollama 监听地址 ollama 安装后…...

cmd执行mysql命令

安装mysql之后如果想使用cmd执行mysql命令&#xff0c;需要怎么操作呢&#xff0c;下面一起看一下。 安装mysql之后&#xff0c;如果直接去cmd窗口执行MySQL命令&#xff0c;窗口可能会提示mysql不是可执行命令。 需要配置系统的环境变量&#xff0c;将mysql的安装路径配置系…...

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗&#xff0c;每一次入侵背后都有一个实体&#xff08;个人或组织&#xff09;”。这一经典观点概括了网络攻防的深层本质。无论是APT&#xff08;高级持续性威胁&#xff09;攻击、零日漏洞利用&#xff0c;还是简单的钓鱼攻击&am…...

【算法】动态规划专题⑦ —— 多重背包问题 + 二进制分解优化 python

目录 前置知识进入正题优化方法&#xff1a;二进制分解实战演练 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 python 【算法】动态规划专题⑥ —— 完全背包问题 python 进入正题 多重背包问题I https://www.acwing.com/problem/content/4/ 题目描述 有…...

详细教程 | 如何使用DolphinScheduler调度Flink实时任务

Apache DolphinScheduler 非常适用于实时数据处理场景&#xff0c;尤其是与 Apache Flink 的集成。DolphinScheduler 提供了丰富的功能&#xff0c;包括任务依赖管理、动态调度、实时监控和日志管理&#xff0c;能够有效简化 Flink 实时任务的管理和部署。通过 DolphinSchedule…...

PHP之hyperf学习笔记

Hyperf Model,Dao&#xff0c;Service&#xff0c;Contronller 路由 使用文件来配置路由&#xff0c;就是和laravel一样的 Router::addGroup(["middleware" > ["web", "auth"],"namespace" > "Hyperf\HttpServer\Contr…...

react的antd表格数据回显在form表单中

1、首先为table添加编辑按钮 {title: 操作,align: center,render: (_: any, record: any) > (<div style{{ display: flex, alignItems: center, justifyContent: space-evenly }}><Buttonsize"small"onClick{() > deitor(record)} style{{ margin…...

【通俗易懂说模型】线性回归(附深度学习、机器学习发展史)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...

【R语言】apply函数族

在R语言中使用循环操作时是使用自身来实现的&#xff0c;效率较低。所以R语言有一个符合其统计语言出身的特点&#xff1a;向量化。R语言中的向量化运用了底层的C语言&#xff0c;而C语言的效率比高层的R语言的效率高。 apply函数族主要是为了解决数据向量化运算的问题&#x…...

传统营销架构在当下如何进行优化转型?

随着市场环境的变化和数字技术的发展&#xff0c;传统营销架构越来越难以适应当下的营销市场。为了适应新时代的要求&#xff0c;企业也需要对营销架构进行优化转型。企业主可以着手从哪些方面进行调整呢&#xff1f;下面就来一同探讨下。 一、强调扁平化原则 扁平化与去中心化…...

QMK启用摇杆和鼠标按键功能

虽然选择了触摸屏&#xff0c;我仍选择为机械键盘嵌入摇杆模块&#xff0c;这本质上是对"操作连续性"的执着。   值得深思的是&#xff0c;本次开发过程中借助DeepSeek的代码生成与逻辑推理&#xff0c;其展现的能力已然颠覆传统编程范式&#xff0c;需求描述可自动…...

计算机网络-SSH基本原理

最近年底都在忙&#xff0c;然后这两天好点抽空更新一下。前面基本把常见的VPN都学习了一遍&#xff0c;后面的内容应该又继续深入一点。 一、SSH简介 SSH&#xff08;Secure Shell&#xff0c;安全外壳协议&#xff09;是一种用于在不安全网络上进行安全远程登录和实现其他安…...

yolov11模型在Android设备上运行【踩坑记录】

0) 参考资料: https://github.com/Tencent/ncnn?tabreadme-ov-file https://github.com/pnnx/pnnx https://github.com/nihui/ncnn-android-yolov5 https://github.com/Tencent/ncnn?tabreadme-ov-file 1) &#xff1a;将xxx.pt模型转化成 xxx.onnx ONNX&#xff08;Ope…...

Linux在x86环境下制作ARM镜像包

在x86环境下制作ARM镜像包&#xff08;如qemu.docker&#xff09;&#xff0c;可以通过QEMU和Docker的结合来实现。以下是详细的步骤&#xff1a; 安装QEMU-user-static QEMU-user-static是一个静态编译的QEMU二进制文件&#xff0c;用于在非目标架构上运行目标架构的二进制文…...

win编译openssl

一、perl执行脚本 1、安装perl脚本 perl安装 2、配置perl脚本 perl Configure VC-WIN32 no-asm no-shared --prefixE:\openssl-x.x.x\install二、编译openssl 1、使用vs工具编译nmake 如果使用命令行nmake编译会提示“无法打开包括文件: “limits.h”“ 等错误信息 所以…...

为什么说,在IT行业中长期从事外包岗位没有前途?

文章目录 前言一、职业发展与技能提升受限二、工作稳定性和归属感缺失三、薪资待遇和福利差异四、行业声誉和求职歧视总结 前言 在IT行业中&#xff0c;由于企业要降低成本、优化资源、分散风险以及满足市场需求和技术需求等原因&#xff0c;存在大量的外包岗位。很多人都说长…...