手把手教你开发第一个HarmonyOS (鸿蒙)移动应用

2023-11-20

⼀、移动应⽤开发的介绍

移动应⽤开发:

  • Android
  • IOS
  • HarmonyOS (鸿蒙)

⼆、HarmonyOS介绍

文档概览-HarmonyOS应用开发官网

2.1 系统的定义

2.1.1 系统的定位

HarmonyOS有三⼤特征:

  • 搭载该操作系统的设备在系统层⾯融为⼀体、形成超级终端,让设备的硬件能⼒可以弹性 扩展,实现设备之间 硬件互助,资源共享。 对消费者⽽⾔,HarmonyOS能够将⽣活场景中的各类终端进⾏能⼒整合,实现不同终端 设备之间的快速连接、能⼒互助、资源共享,匹配合适的设备、提供流畅的全场景体验。
  • ⾯向开发者,实现⼀次开发,多端部署。 对应⽤开发者⽽⾔,HarmonyOS采⽤了多种分布式技术,使应⽤开发与不同终端设备的 形态差异⽆关,从⽽让开发者能够聚焦上层业务逻辑,更加便捷、⾼效地开发应⽤。
  • ⼀套操作系统可以满⾜不同能⼒的设备需求,实现统⼀OS,弹性部署。 对设备开发者⽽⾔,HarmonyOS采⽤了组件化的设计⽅案,可根据设备的资源能⼒和业 务特征灵活裁剪,满⾜不同形态终端设备对操作系统的要求。

2.1.2 系统架构

  • 内核层:提供⼿机操作系统的基础能⼒。HarmonyOS采⽤多内核的系统设计,基于 Linux内核、LiteOS,使⽤了Linux的微内核(使⽤了Linux的最简功 能)
    • Linux内核: ⼿机操作系统的内核
    • LiteOS内核:智能硬件的内核
  • 系统服务层:HarmonyOS的核⼼能⼒集合,这些能⼒是有系统本身决定的,为我们应⽤ 开发提供了服务调⽤功能。系统服务层提供的能⼒是可以被我们开发的应⽤进⾏调⽤的。
  • 框架层:为HarmonyOS的应⽤开发提供了不同语⾔程序调⽤的接⼝

2.2 鸿蒙发展史

2.2.1 “鸿蒙”

盘古开天辟地——⼀⽚混沌(鸿蒙时代) ⽴志要在⼿机系统的国产化道路上开天辟地

2.2.2 发展史

  • 2012年,华为开始规划智能操作系统“鸿蒙”
  • 2019年5⽉,华为申请“鸿蒙”商标
  • 2019年5⽉17⽇,发布鸿蒙系统
  • 2019年8⽉,鸿蒙正式版发布,实⾏开源
  • 2020年9⽉,鸿蒙2.0(beta)
  • 2021年6⽉2⽇晚上,华为线上发布HarmonyOS 2.0---⼿机

2.3 鸿蒙与安卓的区别

2.3.1 内核

  • 安卓:基于Linux的内核设计,对Linux的依赖很⼤(也就是说Android操作系统⼤多数功能都 是依赖Linux)
  • 鸿蒙:采⽤了多内核设计,Linux内核+LiteOS内核,操作系统最⼩限度的依赖Linux内核

2.3.2 运⾏效率

  • 安卓:应⽤的运⾏是基于虚拟机的 (Java---JDK编译器---字节码---虚拟机---操作系统)

  • 鸿蒙:⽅⾈编译器 (Java----⽅⾈编译器---机器码---操作系统)

据说, 鸿蒙系统运⾏效率相较于安卓提升了50%+

2.4 技术特性 与 系统安全

2.4.1 技术特性

  • 硬件互助,资源共享
  • ⼀次开发,多端部署
  • 统⼀OS,弹性部署

2.4.2 系统安全

  • 正确的⼈:⾼效安全的⽤户身份识别
  • 正确的设备:设备的识别
  • 正确的使⽤数据:数据的安全

三、第⼀个鸿蒙应⽤

3.1 开发准备

3.1.1 开发环境搭建(Java)

  • 安装JDK、配置环境变量
  • 下载安装DevEco Studio集成开发环境(基于Idea开发的专⻔⽤于鸿蒙应⽤开发的IDE)

下载地址

华为操作系统DevEco Studio和SDK下载与升级 | HarmonyOS开发者

安装

  • 运行安装包
  • 点击Next
  • 选择安装目录
  • 创建桌面快捷方式
  • 开始安装

运行DevEco Studio

第一次启动开发环境会下载鸿蒙开发所需要的SDK
  • 双击桌⾯快捷⽅式,打开DevEco Studio
  • 开始使⽤
  • 选择SDK⽬录
  • 点击Next进⼊下⼀步
  • 选择Accept,点击Next开始下载SDK
  • 点击Finish完成下载,开始使⽤

3.1.2 注册华为帐号

注册_华为帐号 (huawei.com)

3.2 创建鸿蒙应⽤

3.3 鸿蒙应⽤⽬录结构

3.4 运⾏项⽬

3.4.1 启动鸿蒙模拟器

  • Tools—Device Manager
  • 在弹出的窗⼝装点击 Login 按钮,登录华为帐号
  • 启动⼀个模拟器

3.5 鸿蒙应⽤的启动流程

3.5.1 config.json

config.json 是鸿蒙应⽤的主配置⽂件

  • app 配置 :定义当前应⽤的唯⼀标识
    • bundleName应用的唯一标识(一般包名用公司名+应用名称)
    • version 应⽤的版本
  • module 配置: ⽤于声明当前应⽤的信息(包、主类、主界⾯、功能模块声明、适配设 备类型等等)
    • mainAbility声明当前应用启动时默认加载的Ability

    • deviceType声明当前应用适配的设备类型

    • abilities 声明当前应⽤中每个ability的配置信息

      • 创建一个ability那么在config.json中会自动生成对应的ability的配置信息。

3.5.2 应⽤启动流程

  • 启动鸿蒙应⽤加载config.json⽂件,根据 mainAbility 配置加载启动应⽤的主界⾯

    "mainAbility": "com.example.myapplication.demo01.MainAbility"
  • 执⾏MainAbility的 onStart ⽅法

    MainAbility是⼀个显示界⾯的容器,在onStart⽅法中通过调⽤ setMainRoute ⽅法来指 定当前界⾯容器中显示的视图界⾯

    // ability相当于一个容器(或者说是浏览器窗口),
    // 在容器里面通过填充一个视图slice(html中的body)来展示。
    // MainAbilitySlice就是⼀个界⾯
    super.setMainRoute(MainAbilitySlice.class.getName());
  • 执⾏MainAbilitySlice中的 onStart 完成界⾯的渲染

    slice是⼀个界⾯,界⾯中显示什么视图,就是通过onstart⽅法来加载渲染的

3.5.3 你好,世界哪里来的

$string : 表示引用的一sing,表示要去string文件中寻找键值对,如图寻找key为:mainability_HelloWorld 的值。

四、Ability框架

4.1 Ability介绍

Ability是应⽤所具备能⼒的抽象,也是应⽤程序的重要组成部分。⼀个应⽤可以具备多种能⼒

(即可以包含多个Ability),HarmonyOS⽀持应⽤以Ability为单位进⾏部署。

Ability可以分为 FA(Feature Ability) 和PA (Particle Ability) 两种类型,每种类型为

开发者提供了不同的模板,以便实现不同的业务功能。

  • FA⽀持Page Ability:

    Page模板是FA唯⼀⽀持的模板,⽤于提供与⽤户交互的能⼒。⼀个Page实例可以包含⼀

    组相关⻚⾯,每个⻚⾯⽤⼀个AbilitySlice实例表示。

    ​ 

  • PA⽀持Service Ability和Data Ability:

    • Service模板:⽤于提供后台运⾏任务的能⼒。
    • Data模板:⽤于对外部提供统⼀的数据访问抽象。

4.2 PageAbility

4.2.1PageAbility简介

⼀个PageAbility相当于⼀个⻚⾯的容器(浏览器窗⼝),⼀个AbilitySlice相当于显示在容器

中的⼀个⻚⾯(HTML)

Page模板(以下简称“Page”)是FA唯⼀⽀持的模板,⽤于提供与⽤户交互的能⼒。⼀个Page可以由⼀个或多个AbilitySlice构成,AbilitySlice是指应⽤的单个⻚⾯及其控制逻辑的总和(相当于⼀个HTML⽂件)。在⼀个Abiliy种可以包含多个Slice

商品管理: 	ProductAbility(PageAbility):
 goods-list.html	ProductListSlice
 goods-detail.html 	ProductDetailSlice

4.2.2 创建AbilitySlice

  • AbilitySlice创建slice包中

  • 创建步骤:

    • 创建⼀个类继承 ohos.aafwk.ability.AbilitySlice 类

      public class MainAbilitySlice2 extends AbilitySlice {
      
      }
    • 在 resources/base/layout ⽬录下创建布局⽂件

      <?xml version="1.0" encoding="utf-8"?>
      <DirectionalLayout
       xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:height="match_parent"
       ohos:width="match_parent"
       ohos:orientation="vertical">
       <Text
       ohos:height="match_content"
       ohos:width="match_content"
       ohos:text="这是测试⽂本"
       ohos:text_color="#ff0000"
       ohos:text_size="40vp"></Text>
      </DirectionalLayout> 
    • 在创建的 AbilitySlice 类中重写 onStart ⽅法,调⽤setUIContent⽅法加载布局⽂件

      通过 ResourceTable 加载resouces⽬录下的资源

      public class MainAbilitySlice2 extends AbilitySlice {
          @Override
          protected void onStart(Intent intent) {
              super.onStart(intent);
       		//定义slice视图组件(Java,XML)
       		//setUIContent(int); 加载应⽤的 布局⽂件(xml) 作为当前slice的视图
       		setUIContent(ResourceTable.Layout_ability_main_slice2);
      	}
      }

4.2.3 PageAbility⽣命周期

⼀个Page中可以包含多个Slice,但是只能同时显示⼀个slice,如何设置PageAbility默认

显示的slice?

在⼀个Page Ability中提供了多个声明周期⽅法,这些⽅法在当前PageAbility加载的不同

阶段会⾃定调⽤

说明

INACTIVE状态是一种短暂存在的状态,可理解为“激活中”。

public class MainAbility extends Ability {
     /**
      * 当系统⾸次创建当前PageAbility实例时,⾃动调⽤onstart⽅法。也就是说对于⼀个Page⽽⾔,onStart⽅法只会执⾏⼀次
      */
     public void onStart(Intent intent) {
     	super.onStart(intent);
     	super.setMainRoute(MainAbilitySlice2.class.getName());
     	System.out.println("--------------onStart");
     }
    
     /**
      * 当前Page进⼊active状态进⼊到⼿机前台获取焦点时,会触发onActive⽅法的执⾏
      */
     protected void onActive() {
     	super.onActive();
     	System.out.println("--------------onActive");
 	}
    
     /**
      * 当前PageAbility失去焦点(⻚⾯切⼊到后台、切换到其他Page),触发onInactive⽅法的执⾏
      */
     protected void onInactive() {
     	super.onInactive();
     	System.out.println("--------------onInactive");
     }
    
     /**
      * 当前PageAbility切换到后台,不可⻅时,触发onBackground执⾏
      */
     protected void onBackground() {
     	super.onBackground();
     	System.out.println("--------------onBackground");
     }
     /**
      * 当PageAbility从后台不可⻅状态(⻚⾯在后台、但是没销毁)切换到前台可⻅状态时触发 onForeground执⾏
      */
     protected void onForeground(Intent intent) {
     	super.onForeground(intent);
     	System.out.println("--------------onForeground");
     }
     /**
      * 当前Page销毁时,触发onStop的执⾏
      */
     protected void onStop() {
     	super.onStop();
     	System.out.println("--------------onStop");
     }
}

4.2.4 Slice的两种渲染方式

Slice相当于一个网页,Slice中显示的视图是通过组件来声明的,Slice中的组件加载支持两种方式:

  • Java代码
  • xml布局文件

onStart方法:在Slice实例创建时执行,用于载入当前Slice的视图组件,在onStart方法中通过调用setUIContext来加载视图组件

setUIContext方法提供了2个重载:

setUIContext(int):通过布局⽂件的ID,加载resources/base/layout⽬录下的布局⽂件

完成⻚⾯的渲染

setUIContext(ComponentContainer) :通过加载⼀个使⽤Java代码创建的组件完成⻚⾯

的渲染

XML****⽅式渲染

  • 创建布局⽂件:ability_main_slice2.xml

    <?xml version="1.0" encoding="utf-8"?>
    <DirectionalLayout
        xmlns:ohos="http://schemas.huawei.com/res/ohos"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:orientation="vertical">
    
        <Text
            ohos:height="match_content"
            ohos:width="match_content"
            ohos:text="这是测试文本"
            ohos:text_color="#ff0000"
            ohos:text_size="40vp"></Text>
    
    </DirectionalLayout>
  • 在Slice的onStart⽅法中加载布局⽂件:

    每创建一个布局文件(或者说每个资源都会创建一个ID)都会生成一个ID,所以布局文件调用的是setUIContext(int)方法

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        // 定义slice视图组件(java,xml)
        // setUIContent(int); 加载应用的 布局文件(xml)作为当前slice的试图
        super.setUIContent(ResourceTable.Layout_ability_main_slice2);
    }

Java⽅式渲染

  • 使⽤Java代码创建组件,渲染到slice中

    public class MainAbilitySlice2 extends AbilitySlice {
    
        @Override
        protected void onStart(Intent intent) {
            super.onStart(intent);
            // 定义slice视图组件(java,xml)
            // setUIContent(int); 加载应用的 布局文件(xml)作为当前slice的试图
    //        super.setUIContent(ResourceTable.Layout_ability_main_slice2);
    
            // ComponentContainer(组件容器)
            DirectionalLayout directionalLayout = new DirectionalLayout(this);
            directionalLayout.setOrientation(Component.DRAG_VERTICAL);
            // Component(组件)
            Text text = new Text(this);
            text.setText("Hello Boys");
            text.setHeight(40);
            text.setTextSize(40);
            // 将组件放到组件容器中
            directionalLayout.addComponent(text);
            // 将组件容器渲染到slice中
            setUIContent(directionalLayout);
        }
    }

4.2.5 AbilitySlice间导航

⼀个PageAbility可以包含多个Slice,同⼀时刻只能显示⼀个Slice,但是可以在不同的

Slice之间进⾏跳转——AbilitySlice间的导航

  • 在MainAbilitySlice中添加按钮,并监听按钮的点击事件(略 参考4.3)

  • 创建SecondAbilitySlice(略)

    <?xml version="1.0" encoding="utf-8"?>
    <DirectionalLayout
        xmlns:ohos="http://schemas.huawei.com/res/ohos"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:orientation="vertical">
    
        <!-- 将图片文件存到resource/base/media目录 PS:文件的名字不要用数字开头,因为名字会作为变量名 -->
        <Image
            ohos:height="match_content"
            ohos:width="match_parent"
            ohos:image_src="$media:cat">
        </Image>
    
    </DirectionalLayout>
    public class SecondAbilitySlice extends AbilitySlice {
    
        @Override
        protected void onStart(Intent intent) {
            super.onStart(intent);
            this.setUIContent(ResourceTable.Layout_ability_second);
        }
    }
  • 在MainAbilitySlice中监听按钮的点击事件,导航到SecondAbilitySlice

    public class MainAbilitySlice extends AbilitySlice {
        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            // 在当前slice中渲染试图组件有2中方式:
            // 1. 基于Java代码的渲染
            // 2. 基于xml标签渲染,例如: super.setUIContent(ResourceTable.Layout_ability_main);
            super.setUIContent(ResourceTable.Layout_ability_main);
    
            // 1. 获取id=btn1的按钮组件
            Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1);
    
            // 2.设置按钮事件监听
            MainAbilitySlice _this = this;
            // a.创建事件监听器
            Component.ClickedListener clickedListener = new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    //挑转到SecondAbilitySlice
                    // 从this指代的当前slice跳转到new的slice中
                    _this.present(new SecondAbilitySlice(), new Intent());
                }
            };
            // b.设置组件的事件监听
            btn1.setClickedListener(clickedListener);
    
        }
    
    }

    简化版本

    public class MainAbilitySlice extends AbilitySlice {
        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            // 在当前slice中渲染试图组件有2中方式:
            // 1. 基于Java代码的渲染
            // 2. 基于xml标签渲染,例如: super.setUIContent(ResourceTable.Layout_ability_main);
            super.setUIContent(ResourceTable.Layout_ability_main);
    
            // 1. 获取id=btn1的按钮组件
            Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1);
            
    //        //b.设置组件的事件监听 PS:简化成lambda表达示
            // PS:简化成lambda表达式 因为listener要实现onclick方法
    //        btn1.setClickedListener(clickedListener->{
    //            present(new SecondAbilitySlice(), new Intent() );
    //        });
            
            // b.设置组件的事件监听  因为只有一个方法,可以省略大括号
            btn1.setClickedListener(clickedListener -> present(new SecondAbilitySlice(), new Intent()));
    
        }
    
    }

4.2.6 Slice之间的传值问题

使⽤Intent对象实现slice间的传值

  • MainAbilitySlice

    public class MainAbilitySlice extends AbilitySlice {
        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            super.setUIContent(ResourceTable.Layout_ability_main);
            // 1. 获取id=btn1的按钮组件
            Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1);
            // b.设置组件的事件监听 
            btn1.setClickedListener(clickedListener -> {
                // 在跳转之前的slice将需要传递的数据设置到Intent对象中
                Intent intent1 = new Intent();
                intent1.setParam("productId", "101");
                present(new SecondAbilitySlice(), intent1);
            });
    
        }
    }
  • SecondAbilitySlice

    public class SecondAbilitySlice extends AbilitySlice {
    
        @Override
        protected void onStart(Intent intent) {
            super.onStart(intent);
            this.setUIContent(ResourceTable.Layout_ability_second);
            // 在跳转后的slice的onStart方法中,从intent对象中获取数据
            if (intent != null) {
                // 因为intent.getParam()返回的是IntentParams, 所以先获取IntentParams然后再获取值
                IntentParams params = intent.getParams();
                String productId = (String) params.getParam("productId");
                // 获取到id=text1的文本组件
                Text text = (Text) findComponentById(ResourceTable.Id_text1);
                // 将获取到的商品ID设置到text文本组件
                text.setText(productId);
            }
        }
    }

4.3 组件的事件监听

4.3.1 在MainAbilitySlice布局文件添加按钮

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <Image
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:image_src="$media:icon">
    </Image>

    <Text
        ohos:id="$+id:text_helloworld"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:background_element="$graphic:background_ability_main"
        ohos:layout_alignment="horizontal_center"
        ohos:text="$string:mainability_HelloWorld"
        ohos:text_size="40vp"/>
    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_parent"
        ohos:padding="5vp"
        ohos:text="点我试试!"
        ohos:text_size="40vp"
        ohos:background_element="#a0b0c0"></Button>

</DirectionalLayout>

当我们在Button使用$+id:btn1时,这个组件就会在ResourceTable中产生一个唯一标识

4.3.2 监听按钮的点击事件

  • 在加载布局文件的Slice类中,获取按钮组件,设置点击事件的监听器

    package com.example.myapplicationdemo01.slice;
    
    import com.example.myapplicationdemo01.ResourceTable;
    import ohos.aafwk.ability.AbilitySlice;
    import ohos.aafwk.content.Intent;
    import ohos.agp.components.Button;
    import ohos.agp.components.Component;
    
    public class MainAbilitySlice extends AbilitySlice {
        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            // 在当前slice中渲染试图组件有2中方式:
            // 1. 基于Java代码的渲染
            // 2. 基于xml标签渲染,例如: super.setUIContent(ResourceTable.Layout_ability_main);
            super.setUIContent(ResourceTable.Layout_ability_main);
    
            // 1. 获取id=btn1的按钮组件
            Button btn = (Button) this.findComponentById(ResourceTable.Id_btn1);
    
            // 2.设置按钮事件监听
            // a.创建事件监听器
            Component.ClickedListener clickedListener = new Component.ClickedListener(){
                @Override
                public void onClick(Component component) {
                    System.out.println("--------触发了点击事件");
                }
            };
            // b.设置组件的事件监听
            btn.setClickedListener(clickedListener);
        }
    }
    
  • 可以使用同一个监听器监听多个组件的事件,如果点击不同的组件执行的业务不同,则可以通过组件判断来执行不同的业务

    // 1. 获取id=btn1的按钮组件
    Button btn1 = (Button) this.findComponentById(ResourceTable.Id_btn1);
    Button btn2 = (Button) this.findComponentById(ResourceTable.Id_btn2);
    
    // 2.设置按钮事件监听
    // a.创建事件监听器
    Component.ClickedListener clickedListener = new Component.ClickedListener(){
        @Override
        public void onClick(Component component) {
            // Component参数 表示监听的组件
            if (component ==  btn1) {
                System.out.println("--------aaa");
            } else if (component == btn2) {
                System.out.println("~~~~~~~~bbb");
            }
    
        }
    };
    // b.设置组件的事件监听
    btn1.setClickedListener(clickedListener);// 输出aaa
    btn2.setClickedListener(clickedListener);// 输出bbb
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手把手教你开发第一个HarmonyOS (鸿蒙)移动应用 的相关文章

  • Pytorch权重初始化方法——Kaiming、Xavier

    Pytorch权重初始化方法 Kaiming Xavier 结论 结论写在前 Pytorch线性层采取的默认初始化方式是Kaiming初始化 这是由我国计算机视觉领域专家何恺明提出的 我的探究主要包括 为什么采取Kaiming初始化 考察K
  • window10 设置 cmd 与 PowerShell 格式UTF-8

    win R键 输入 regedit 进入 如果进入不了就去下载 regedit cmd 接下来我们进入对应目录添加对应字符串 好了我们重启vscode运行即可 PowerShell 原CodePage数值数据 更改CodePage数值数据

随机推荐

  • Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 实践 参考 前言 遮罩纹理 mask texture 是本章要介绍的最后一种纹理 它非常有用 在很多商业游戏中 都可以见到它的身影 那么什么是遮罩呢 简单来讲 遮罩允许我们
  • WIN10 系统,笔记本电脑显示 “未检测到摄像头”

    笔记本电脑无缘无故不能使用摄像头了 在打开腾讯会议的时候显示 未检测到摄像头 检测设备是否连接 打开设备管理器发现没有 照相机 这个选项 并且在狠心下载360卫士进行系统修复后和驱动检测发现不是驱动的问题之后 摄像头仍然无法使用 在尝试多种
  • 如何使用Minio进行对象存储和数据管理

    Minio是一个开源的对象存储服务器 可用于存储和管理各种类型的数据 包括图像 视频 文档等等 本文将介绍如何安装和配置Minio 使用Minio进行对象存储 以及如何利用Minio的高级功能和解决常见问题 一 简介 1 1 什么是Mini
  • 【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取

    最近开始调试Linux 的测试版 需要开发网络设置相关功能 其实这一块以前也做过 但是都忘记了 可见沉淀的重要性 1 ip 掩码设置和获取 通过int ioctl int d int request 这个函数可以获取到 其中 IP设置 SI
  • C语言算法题之二叉树的路径和

    思路 二叉树顾名思义就是一个最多有两个子节点的数据结构 如下图所示 其中像数字7和8 5和6这四个节点都叫做叶子节点 其他的节点都是叫做根节点 路径有 1 2 4 7 路径和为1 2 4 7 14 1 2 4 8 路径和为1 2 4 8 1
  • 算法 - 前缀树

    目录 一 前缀树含义 二 代码实现 一 前缀树实现 方式一 方式二 二 暴力实现 一 前缀树含义 前缀树 把一个 最小 单位的数据看成一个节点到另一个节点的路径 每个节点有两个属性 一个是所有数据经过这个节点的次数pass 一个是这个节点作
  • CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below m...

    CUDA内核错误可能会在其他API调用时异步报告 因此下面的堆栈跟踪可能是不正确的 为了调试 考虑传递CUDA LAUNCH BLOCKING 1 这个错误提示告诉你 你在使用CUDA进行计算的时候可能会出现内核错误 并且这些错误可能在其他
  • CVPR ICCV ECCV 论文列表 // 研究机构 链接

    文章目录 会议 CVPR 一年一次 IEEE Conference on Computer Vision and Pattern Recognition ICCV 两年一次 奇数年 IEEE International Conference
  • 【第38篇】MixConv:混合深度卷积核

    文章目录 摘要 1 简介 2 相关工作 3 MixConv 3 2 MixConv 设计选择 3 3 MobileNets 上的 MixConv 性能 3 4 消融研究 4 MixNet 4 1 架构搜索 4 2 ImageNet 上的 M
  • Linux离线安装 RabbitMQ(RabbitMQ单机安装)

    1 下载erlang和rabbitmq安装包 1 下载Erlang路径 https github com erlang otp releases 2 下载RabbitMQ路径 https github com rabbitmq rabbit
  • SQL查询与修改数据库逻辑文件名,移动数据库存储路径示例

    Author htl258 Tony Date 2010 06 26 21 51 30 Version Microsoft SQL Server 2008 RTM 10 0 1600 22 Intel X86 Jul 9 2008 14 4
  • 万向锁,简单表述,一文看懂

    万向锁问题 看了下百度知乎 居然 很少有说清楚的 想起自己第一次接触的时候 也是一头雾水 特此解释 1 什么是万向锁问题 欧拉角顺序有很多 当中比较常用的 一种 便是用 偏航 俯仰 滚转 yaw pitch roll 三个角度来描述一个旋转
  • Flink_05_状态(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 状态 状态就是一块内存 一个变量 如果要访问历史窗口 或批次 的数据
  • 运动规划入门

    原创文章 作者 tloinny 如若转载 请注明出处 古月居 https www guyuehome com 5652 感谢古月老师 古 月给的机会 让笔者有幸成为古月居签约作者 此后笔者将在古月居发布更多Robotic相关的博文 当然我也
  • gcc搜索动态链接库的路径优先级排序

    GCC运行时 Linux动态链接库的搜索路径按优先级排序为 1 编译目标代码时 Wl rpath 指定的动态库搜索路径 当指定多个动态库搜索路径时 路径之间用冒号 分隔 2 环境变量 LD LIBRARY PATH 指定的动态库搜索路径 3
  • 泊松重建算法原理介绍

    目录 1 泊松重建算法 2 泊松重建核心思想及原理 3 泊松算法流程 本文出自CSDN点云侠 原文链接 爬虫自重 把自己当个人 1 泊松重建算法 泊松重建是Kazhdan M在2006年提出的基于八叉树和泊松方程的一种网格三维重建算法 其本
  • python 爬取google总结

    1 问题 目前主流的搜索引擎 非google莫属 但其对于非法 流量异常 爬虫 请求的封锁也是异常严厉 本人前段时间有个脚本用到了谷歌搜索 具体见python之由公司名推算出公司官网 余弦相似度 当时直接使用的是一个python开源项目 但
  • Python3:官方文档的链接

    1 numpy https www numpy org cn article https numpy org 2 pandas https pandas pydata org 3 matplotlib https matplotlib or
  • 字符串最后一个单词的长度

    描述 计算字符串最后一个单词的长度 单词以空格隔开 字符串长度小于5000 输入描述 输入一行 代表要计算的字符串 非空 长度小于5000 输出描述 输出一个整数 表示输入字符串最后一个单词的长度 示例1 输入 hello nowcoder
  • 手把手教你开发第一个HarmonyOS (鸿蒙)移动应用

    移动应 开发的介绍 移动应 开发 Android IOS HarmonyOS 鸿蒙 HarmonyOS介绍 文档概览 HarmonyOS应用开发官网 2 1 系统的定义 2 1 1 系统的定位 HarmonyOS有三 特征 搭载该操作系统的