Android--Jetpack--Navigation详解

须知少日拏云志,曾许人间第一流

一,定义

Navigation 翻译成中文就是导航的意思。它是谷歌推出的Jetpack的一员,其目的主要就是来管理页面的切换和导航。

Activity 嵌套多个 Fragment 的 UI 架构模式已经非常普遍,但是对 Fragment 的管理,我们一般通过 FragmentManager 和 FragmentTransaction 来管理 Fragment 之间的切换。页面的切换通常还包括对应用程序 App bar 的管理、Fragment 间的切换动画,以及 Fragment 间的参数传递。纯代码的方式使用起来不是特别友好,并且 Fragment 和 App bar 在管理和使用的过程中显得混乱。

使用Navigation可以很方便的管理和切换Fragment。

二,角色介绍

Navigation组件由三部分构成:

1)导航图(xml文件)包含所有导航相关信息的 XML 资源,其中包含所有目的地和操作。该图表会显示应用的所有导航路径。

2)NavHostFragment导航宿主是 Navigation 组件的核心部分之一。导航宿主是一个空容器,用户在应用中导航时,目的地会在该容器中交换进出。

3)NavController导航到目的地是使用NavController 完成的,它是一个在NavHost中管理应用导航的对象。每个NavHost均有自己的相应NavController 。

三,Navigation的优点

1)可视化的页面导航图,类似于 Apple Xcode 中的 StoryBoard,便于我们理清页面关系。

2)通过 destination 和 action 完成页面间的导航。

 3)方便添加页面切换动画。

 4)页面间类型安全的参数传递。

 5)通过 NavigationUI,对菜单、底部导航、抽屉菜单导航进行统一的管理。

四,基本使用

1,在app的build.gradle中添加引用:

implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'

2,在res目录下创建导航图(xml文件):

 

 点击ok就会生成xml文件

3,创建fragment:

创建三个fragment,分别为YZ1Fragment,YZ2Fragment,YZ3Fragment

public class YZ1Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_yz1,container,false);
    }

}

fragment_yz1:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#223355">

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我是第一页"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="跳转第二页"
        android:textAllCaps="false"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message" />

</androidx.constraintlayout.widget.ConstraintLayout>
public class YZ2Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_yz2,container,false);
    }
}

fragment_yz2:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#dd2233">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="16dp"
        android:text="第二页"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="返回第一页"
        android:textAllCaps="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="前往第三页"
        android:textAllCaps="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn" />

</androidx.constraintlayout.widget.ConstraintLayout>
public class YZ3Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_yz3,container,false);
    }
}

fragment_yz3:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#33ff22">


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="16dp"
        android:text="第三页"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="跳到第二页"
        android:textAllCaps="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

4,回到yuanzhen_nav.xml中,点击添加:

添加三个fragment :

然后收到添加跳转方向:

 

 就会自动生成代码:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/yuanzhen_nav"
    app:startDestination="@id/YZ1Fragment">
    <fragment
        android:id="@+id/YZ1Fragment"
        android:name="com.yuanzhen.mynavigation.YZ1Fragment"
        android:label="YZ1Fragment" >
        <action
            android:id="@+id/action_YZ1Fragment_to_YZ2Fragment2"
            app:destination="@id/YZ2Fragment" />
    </fragment>
    <fragment
        android:id="@+id/YZ2Fragment"
        android:name="com.yuanzhen.mynavigation.YZ2Fragment"
        android:label="YZ2Fragment" >
        <action
            android:id="@+id/action_YZ2Fragment_to_YZ3Fragment2"
            app:destination="@id/YZ3Fragment" />
        <action
            android:id="@+id/action_YZ2Fragment_to_YZ1Fragment2"
            app:destination="@id/YZ1Fragment" />
    </fragment>
    <fragment
        android:id="@+id/YZ3Fragment"
        android:name="com.yuanzhen.mynavigation.YZ3Fragment"
        android:label="YZ3Fragment" >
        <action
            android:id="@+id/action_YZ3Fragment_to_YZ2Fragment2"
            app:destination="@id/YZ2Fragment" />
    </fragment>
</navigation>

这里的action代表的就是跳转路径。

5,在fragment中实现跳转代码:

public class YZ1Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_yz1,container,false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button btn=view.findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(R.id.action_YZ1Fragment_to_YZ2Fragment2);
            }
        });
    }

}
public class YZ2Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_yz2,container,false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button btn=view.findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(R.id.action_YZ2Fragment_to_YZ1Fragment2);
            }
        });

        Button btn2=view.findViewById(R.id.btn2);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(R.id.action_YZ2Fragment_to_YZ3Fragment2);
            }
        });
    }
}
public class YZ3Fragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_yz3,container,false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button btn=view.findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(R.id.action_YZ3Fragment_to_YZ2Fragment2);
            }
        });
    }

}

6,在Activity添加fragment:

public class MainActivity extends AppCompatActivity {
    private NavController navController;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        navController = Navigation.findNavController(this, R.id.frag);
        NavigationUI.setupActionBarWithNavController(this, navController);

    }


}

activity_main:

<?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"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/frag"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/yuanzhen_nav"/>

</androidx.constraintlayout.widget.ConstraintLayout>

运行效果:

 五,添加导航栏

1,在res目录下添加menu:

2,menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/YZ1Fragment"
        android:icon="@mipmap/pic_article_default"
        android:title="首页"/>
    <item
        android:id="@+id/YZ2Fragment"
        android:icon="@mipmap/tell_normal"
        android:title="第二页"/>
    <item
        android:id="@+id/YZ3Fragment"
        android:icon="@mipmap/video_call_default"
        android:title="第三页"/>
</menu>

注意,这里的id就是你要跳转的fragment名称

3,在activity_main添加新的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <fragment
        android:id="@+id/frag"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="9"
        app:defaultNavHost="true"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/yuanzhen_nav"/>
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/btm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:menu="@menu/menu"/>

</LinearLayout>

4,在MainActivity添加代码:

public class MainActivity extends AppCompatActivity {
    private NavController navController;
    BottomNavigationView bottomNavigationView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bottomNavigationView=findViewById(R.id.btm);
        navController = Navigation.findNavController(this, R.id.frag);
        NavigationUI.setupWithNavController(bottomNavigationView,navController);
    }
}

实现效果:

 六,添加动画效果

添加动画效果非常简单:

1,打开yuanzhen_nav.xml文件

2,点击试图的跳转线:

3, 

有四个动画可以选择

选择之后yaunzhen_nav文件如下:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/yuanzhen_nav"
    app:startDestination="@id/YZ1Fragment">
    <fragment
        android:id="@+id/YZ1Fragment"
        android:name="com.yuanzhen.mynavigation.YZ1Fragment"
        android:label="YZ1Fragment" >
        <action
            android:id="@+id/action_YZ1Fragment_to_YZ2Fragment2"
            app:destination="@id/YZ2Fragment"
            app:enterAnim="@anim/nav_default_pop_enter_anim"
            app:exitAnim="@anim/nav_default_pop_enter_anim"
            app:popEnterAnim="@anim/nav_default_pop_exit_anim"
            app:popExitAnim="@anim/nav_default_pop_exit_anim" />
    </fragment>
    <fragment
        android:id="@+id/YZ2Fragment"
        android:name="com.yuanzhen.mynavigation.YZ2Fragment"
        android:label="YZ2Fragment" >
        <action
            android:id="@+id/action_YZ2Fragment_to_YZ3Fragment2"
            app:destination="@id/YZ3Fragment"
            app:enterAnim="@anim/nav_default_enter_anim"
            app:exitAnim="@anim/nav_default_exit_anim"
            app:popEnterAnim="@anim/nav_default_enter_anim"
            app:popExitAnim="@anim/nav_default_pop_exit_anim" />
        <action
            android:id="@+id/action_YZ2Fragment_to_YZ1Fragment2"
            app:destination="@id/YZ1Fragment" />
    </fragment>
    <fragment
        android:id="@+id/YZ3Fragment"
        android:name="com.yuanzhen.mynavigation.YZ3Fragment"
        android:label="YZ3Fragment" >
        <action
            android:id="@+id/action_YZ3Fragment_to_YZ2Fragment2"
            app:destination="@id/YZ2Fragment" />
    </fragment>
</navigation>

也可以自己去自定义动画

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于“Python”的核心知识点整理大全21

9.3.2 Python 2.7 中的继承 在Python 2.7中&#xff0c;继承语法稍有不同&#xff0c;ElectricCar类的定义类似于下面这样&#xff1a; class Car(object):def __init__(self, make, model, year):--snip-- class ElectricCar(Car):def __init__(self, make, model, year):supe…

VHDL实验:基于有限状态机实现秒表

题目要求&#xff1a; 利用有限状态机实现实现一个具有启动、停止、清零功能的秒表&#xff0c;显示格式&#xff1a;分&#xff1a;秒&#xff1a;十分秒。启动、停止、清零由一个按键控制&#xff0c;按键按下时&#xff0c;功能按启动、停止、清零顺序循环。 思路分析&…

【NTN 卫星通信】Starlink,卫星互联网的技术革命(一)

1. 什么是Starlink Starlink是由Elon Musk创立的私人太空探索公司SpaceX提供的卫星互联网服务。它旨在为世界上传统互联网服务速度慢或不可用的偏远地区提供价格合理的高速互联网。 为什么Starlink很重要&#xff1f;   Starlink之所以重要&#xff0c;是因为它有可能为数百万…

万能微信在线考试系统:适用于任何行业的在线考试系统 附带完整的搭建教程

互联网技术的发展&#xff0c;线上教育、线上考试逐渐成为主流。特别是在疫情期间&#xff0c;许多传统的线下考试都被迫转为线上。然而&#xff0c;对于许多机构、企业来说&#xff0c;搭建一个稳定、安全的在线考试系统并非易事。这需要专业的技术团队、充足的时间和资源投入…

基于Java SSM框架实现二手交易平台网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现二手交易平台网站系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认…

逆向获取某音乐软件的加密(js逆向)

本文仅用于技术交流&#xff0c;不得以危害或者是侵犯他人利益为目的使用文中介绍的代码模块&#xff0c;若有侵权请联系作者更改。 老套路&#xff0c;打开开发者工具&#xff0c;直接开始找到需要的数据位置&#xff0c;然后观察参数&#xff0c;请求头&#xff0c;cookie是…

TypeScript入门实战笔记 -- 04 什么是字面量类型、类型推断、类型拓宽和类型缩小?

&#x1f34d;开发环境 1&#xff1a;使用vscode 新建一个 04.Literal.ts 文件&#xff0c;运行下列示例。 2&#xff1a;执行 tsc 04.Literal.ts --strict --alwaysStrict false --watch 3&#xff1a;安装nodemon( 全局安装npm install -g nodemon ) 检测.js文件变化重启项…

网络层--TCP/UDP协议

目录 一、TCP/UDP协议介绍 1、UDP(User Datagram Protocol)--用户数据报协议 1.1 UDP报文格式 1.2 UDP协议的特性 2、TCP(Transmission Control Protocol )--传输控制协议 2.1 TCP报文格式 2.2 TCP协议的特性 2.3 TCP三次握手 2.4 四次挥手 三、TCP和UDP的区别 四、t…

HTML字体阴影

目录 1.阴影颜色 color2.水平轴和垂直轴3.模糊半径 blur 效果如下&#xff1a; h-shadow必需&#xff0c;水平阴影的位置&#xff0c;允许负值v-shadow必须&#xff0c;垂直阴影的位置&#xff0c;允许负值blur可选&#xff0c;模糊的距离color可选&#xff0c;阴影的颜色 1…

WebSocket开发

目录 前言 1.介绍 2.原理解析 3.简单的聊天室搭建 4.点到点消息传输 总结 前言 WebSocket 是互联网项目中画龙点睛的应用&#xff0c;可以用于消息推送、站内信、在线聊天等业务。 1.介绍 WebSocket 是一种基于 TCP 的新网络协议&#xff0c;它是一种持久化的协议&…

vim + ctags 跳转, 查看函数定义

yum install ctags Package ctags-5.8-13.el7.x86_64 already installed and latest version 创建 /home/mzh/pptp-master/tags.sh #!/usr/bin/shWORKDIR/home/mzh/pptp-masterfind ${WORKDIR} -name "*.[c|h]" | xargs ctags -f ${WORKDIR}/tags find /usr/inclu…

花裤衩vue-element-admin-master

这个模板是集成度比较高的 在实习的时候老是依赖装不上 今天在公司 把版本切换到16.17.1 一次就成功了 里面的工具还是比较多的&#xff0c; vue3里开源模板里工具比较多的是vben&#xff0c;它同样安装依赖比较难搞

React Native android环境搭建,使用夜神模拟器进行开发(适用于0.73+版本)

前言 本文基于&#xff1a;“react-native” : “^0.73.0” 1.安装 Node Node.js&#xff0c;下载时选择 > 18 版本 2.下载并安装 JDK Java SE Development Kit (JDK)&#xff0c;下载时选择 17 版本 安装 验证是否安装成功 打开命令提示符输入 javac -version 回车 3.…

Springboot集成支付宝支付---完整详细步骤

网页操作步骤 1.进入支付宝开发平台—沙箱环境 使用开发者账号登录开放平台控制平台 2.点击沙箱进入沙箱环境 说明&#xff1a;沙箱环境支持的产品&#xff0c;可以在沙箱控制台 沙箱应用 > 产品列表 中查看。 3.进入沙箱&#xff0c;配置接口加签方式 在沙箱进行调试前…

网页设计--第7次课后作业

已在qq课程群发送了课程的相关资料。 1、安装nodejJS。 2、安装vue-cli。 3、新建一个自己的vue工程化项目。 4、修改默认的vue项目&#xff0c;体会main.js,app.vue以及其他vue文件之间的调用关系&#xff0c;明白vue工程化项目的运行原理。 可以参考视频讲解&#xff08;…

SQL排列组合

SQL排列组合 1、排列组合概述2、SQL排列组合2.1、排列2.2、组合3、SQL排列组合的应用1、排列组合概述 排列组合是针对离散数据常用的数据组织方法,本节将分别介绍排列、组合的SQL实现方法,并结合实例着重介绍通过组合对数据的处理 如何使用SQL实现排列与组合?本节将通过介绍…

LeetCode 2132. 用邮票贴满网格图:二维前缀和 + 二维差分

【LetMeFly】2132.用邮票贴满网格图&#xff1a;二维前缀和 二维差分 力扣题目链接&#xff1a;https://leetcode.cn/problems/stamping-the-grid/ 给你一个 m x n 的二进制矩阵 grid &#xff0c;每个格子要么为 0 &#xff08;空&#xff09;要么为 1 &#xff08;被占据&…

欧盟eDelivery的AS4解决方案

为实现绿色和数字欧洲的愿景&#xff0c;欧盟启动了“数字欧洲计划&#xff08;DEP&#xff09;”&#xff0c;总预算为75.9亿欧元&#xff0c;重点是将数字技术带给企业、公民和公共行政部门。它将建立数字能力和基础设施&#xff0c;并以创建数字市场为目标&#xff0c;主要通…

escapeshellarg参数绕过和注入的问题

escapeshellcmd escapeshellcmd(string $command): string command--要转义的命令。 escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数&#xff0c;或者 执行操作符 之前进行转义。 …

apk反编译修改教程系列---简单给app添加启动弹窗 添加对话框 跳转指定网页等【七】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…