HarmonyOS实战开发-实现UIAbility内和UIAbility间页面的跳转

介绍

本篇Codelab基于Stage模型下的UIAbility开发,实现UIAbility内和UIAbility间页面的跳转。包含如下功能:

  1. UIAbility内页面的跳转。
  2. 跳转到指定UIAbility的首页。
  3. 跳转到指定UIAbility的指定页面(非首页)。

最终效果图如下:

相关概念

  • UIAbility组件概述:UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。
  • UIAbilityContext:UIAbilityContext是UIAbility的上下文环境,继承自Context,提供UIAbility的相关配置信息以及操作UIAbility和ServiceExtensionAbility的方法。
  • 页面路由:提供通过不同的url访问不同的页面,包括跳转到应用内的指定页面、用应用内的某个页面替换当前页面、返回上一页面或指定的页面等。
  • Text:文本组件,用于呈现一段文本信息。
  • Button:按钮组件,可快速创建不同样式的按钮。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  1. 完成DevEco Device Tool的安装
  2. 完成RK3568开发板的烧录

3.搭建开发环境。

  1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──device/src/main/ets              // device模块的代码区
│  ├──pages
│  │  ├──Index.ets                  // SecondAbility的Index页面
│  │  └──Second.ets                 // SecondAbility的Second页面
│  ├──secondability
│  │  └──SecondAbility.ets          // 程序入口类
├──device/src/main/resources        // device模块的资源文件目录
├──entry/src/main/ets               // entry模块的代码区
│  ├──common
│  │  ├──constants
│  │  │  ├──CommonConstants.ets     // 公共常量类
│  │  │  └──StyleConstants.ets	    // 样式常量类
│  │  ├──utils
│  │  │  ├──GlobalContext.ets       // 全局变量控制类
│  │  │  └──Logger.ets	            // 日志打印类
│  ├──entryability
│  │  └──EntryAbility.ts            // 程序入口类
│  ├──model
│  │  └──ButtonClickMethod.ets      // 按钮点击后调用的方法类
│  ├──pages
│  │  ├──Index.ets                  // EntryAbility的Index页面
│  │  └──Second.ets                 // EntryAbility的Second页面
└──entry/src/main/resources         // entry模块的资源文件目录

UIAbility内页面的跳转

entry模块中,EntryAbility内页面的跳转可以通过页面路由router来实现。页面路由router根据页面url找到目标页面,从而实现跳转。效果图如下:

1.实现UIAbility内页面的跳转,我们首先需要构建两个页面。在“Project”窗口,点击“entry > src > main > ets > pages”,打开“Index.ets”文件,可以看到EntryAbility的Index页面由一个Image组件、两个Text组件、三个Button组件组成。“Index.ets”文件的示例代码如下:

@Entry
@Component
struct Index {
  @State text: string = '';
  @State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;

  build() {
    Column() {
      Image($r('app.media.right'))
        ...

      Text($r('app.string.main_index_page_name'))
        ...

      // 条件渲染:当text的值不为空时,显示该组件
      if (this.text !== '') {
        Text(this.text)
          ...
      }

      // 导航到EntryAbility的Second Page
      Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...

      // 导航到SecondAbility的Index Page
      Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...

      // 导航到SecondAbility的Second Page
      Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

2.在“Project”窗口,打开“entry > src > main > ets”,右键点击“pages”文件夹,选择“New > Page”,命名为“Second”。可以看到EntryAbility的Second页面由一个Image组件、两个Text组件、一个Button组件组成。“Second.ets”文件的示例代码如下:

@Entry
@Component
struct Second {
  ...

  build() {
    Column() {
      Image($r('app.media.left'))
        ...

      Text($r('app.string.main_second_page_name'))
        ...

      Text(`${this.src}:${this.count}`)
        ...

      // 返回到EntryAbility的Index Page
      Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

3.从entry模块的Index页面跳转到Second页面,并进行数据传递,通过页面路由router来实现。需要如下几个步骤:

  • 给两个页面导入router模块。
  • 在EntryAbility的Index页面中,点击“导航到EntryAbility的Second Page”按钮后,调用ButtonClickMethod类中的toEntryAbilitySecond方法,跳转到EntryAbility的Second页面。使用router.pushUrl实现跳转,可以通过params来向新页面传入参数,示例代码如下:
// 导入router模块
import router from '@ohos.router';
  
// 导航到EntryAbility的Second Page
toEntryAbilitySecond() {
  router.pushUrl({
    url: 'pages/Second',
    params: {
      src: textMessage,
      count: CommonConstants.NUM_VALUES[0]
    }
  });
}
  • Second页面通过router.getParams()方法获取Index页面传递过来的自定义参数,并用一个Text文本展示从Index页面传递过来的数据,示例代码如下:
@Entry
@Component
struct Second {
  ...
  // 获取Index页面传递过来的自定义参数
  params = router?.getParams();
  @State src: string = this.params == undefined ? '-' : (this.params as Record<string,Object>)['src'] as string;
  @State count: number = this.params == undefined ? 0 : (this.params as Record<string,Object>)['count'] as number;
  
  build() {
    Column() {
      Image($r('app.media.left'))
        ...
  
      Text($r('app.string.main_second_page_name'))
        ...
  
      // 用一个Text文本展示从Index页面传递过来的数据      
      Text(`${this.src}:${this.count}`)
        ...
  
      // 返回到EntryAbility的Index Page
      Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

4.从entry模块的Second返回到Index页面,使用router.back来实现。在EntryAbility的Second页面中,点击“返回到EntryAbility的Index Page”按钮后,返回到EntryAbility的Index页面,示例代码如下:

// 返回到EntryAbility的Index Page
router.back();

跳转到指定UIAbility的首页

实现UIAbility间页面的跳转,需要启动另外一个UIAbility,可以通过UIAbilityContext的startAbility的方法来完成。本篇Codelab是用两个模块(entry和device),实现UIAbility间页面的跳转。跳转到指定UIAbility的首页,效果图如下:

1.在本章节中,实现跳转到指定UIAbility的首页,我们需要新建一个模块。在“Project”窗口,右键点击“entry 文件夹”,选择“New > Module > Empty Ability > Next”,在“Module name”中给新建的模块命名为“device”,点击“Next”,在“Ability name”中给新建模块的Ability命名为“SecondAbility”,点击“Finish”。可以看到文件目录结构如下:

2.构建SecondAbility的首页。在“Project”窗口,点击“device > src > main > ets > pages”,打开“Index.ets”文件,可以看到SecondAbility的Index页面由一个Image组件、两个Text组件、一个Button组件组成。“Index.ets”文件的示例代码如下:

@Entry
@Component
struct Index {
  ...

  build() {
    Column() {
      Image($r('app.media.left'))
        ...

      Text($r('app.string.second_index_page_name'))
        ...

      Text(`${this.src}:${this.count}`)
        ...

      // 停止SecondAbility自身
      Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

3.从entry模块的EntryAbility的首页,跳转到SecondAbility的首页,即从EntryAbility的Index页面跳转到SecondAbility的Index页面。通过UIAbilityContext的startAbility方法来实现。

  • 首先需要在EntryAbility的“Index.ets”文件中获取UIAbilityContext,示例代码如下:
// 获取UIAbilityContext
let context = getContext(this) as common.UIAbilityContext;

说明: 如果需要使用UIAbilityContext中的方法,需要在对应的页面获取相应的UIAbilityContext。

  • 在EntryAbility的Index页面中,点击“导航到SecondAbility的Index Page”按钮后,调用ButtonClickMethod类中的toSecondAbilityIndex方法,拉起SecondAbility的Index页面。使用UIAbilityContext.startAbility来实现,可以通过parameters来向被拉起方传递参数,示例代码如下:
// 导航到SecondAbility的Index Page
toSecondAbilityIndex(context: common.UIAbilityContext) {
  let want: Want = {
    'deviceId': '',
    'bundleName': CommonConstants.BUNDLE_NAME,
    'abilityName': CommonConstants.SECOND_ABILITY_NAME,
    'moduleName': CommonConstants.DEVICE_MODULE_NAME,
    'parameters': {
       src: textMessage,
       count: CommonConstants.NUM_VALUES[1]
     }
  };
  context.startAbility(want).then(() => {
    Logger.info(CommonConstants.TAG, `start second ability index page succeed with ${JSON.stringify(want)}`);
  }).catch((error: Error) => {
    Logger.error(CommonConstants.TAG, `start second ability index page failedwith ${error}`);
  });
}
  • 在SecondAbility的Index页面,获取从EntryAbility的Index页面传递过来的自定义参数,并用一个Text文本展示从Index页面传递过来的数据,示例代码如下:
@Entry
@Component
struct Index {
  // 获取从EntryAbility的Index页面传递过来的自定义参数
  secondAbilityWant?: Want = GlobalContext.getContext().getObject('secondAbilityWant');
  @State src: string = this.secondAbilityWant?.parameters?.src as string ?? '-';
  @State count: number = this.secondAbilityWant?.parameters?.count as number ?? 0;

  build() {
    Column() {
      Image($r('app.media.left'))
        ...

      Text($r('app.string.second_index_page_name'))
        ...

      // 用一个Text文本展示从Index页面传递过来的数据
      Text(`${this.src}:${this.count}`)
        ...

      // 停止SecondAbility自身
      Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

4.在SecondAbility的Index页面,点击“停止SecondAbility自身”按钮,使用UIAbilityContext.terminateSelf方法手动销毁Ability。示例代码如下:

// 停止SecondAbility自身
terminateSecondAbility(context: common.UIAbilityContext) {
  context.terminateSelf().then(() => {
    Logger.info(CommonConstants.TAG, 'terminate second ability self succeed');
  }).catch((error: Error) => {
    Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error}`);
  });
}

5.运行时,需要在DevEco Studio的entry模块中勾选“Deploy Multi Hap Packages”,如下图所示:

跳转到指定UIAbility的指定页面(非首页)

跳转到指定UIAbility的指定页面(非首页),本章节以从EntryAbility的Index页面跳转到SecondAbility的Second页面为例。只需要在本文档“跳转到指定UIAbility的首页”章节的基础上,另外在device模块中构建一个Second页面。效果图如下:

1.构建SecondAbility的Second页面。在“Project”窗口,打开“device > src > main > ets”,右键点击“pages”文件夹,选择“New > Page”,命名为“Second”。可以看到文件目录结构如下:

2.可以看到SecondAbility的Second页面由一个Image组件、两个Text组件、一个Button组件组成。“Second.ets”文件的示例代码如下:

@Entry
@Component
struct Second {
  // 用来接收parameters参数传过来的值
  secondAbilityWant?: Want = GlobalContext.getContext().getObject('secondAbilityWant');
  @State src: string = this.secondAbilityWant?.parameters?.src as string ?? '-';
  @State count: number = this.secondAbilityWant?.parameters?.count as number ?? 0;

  build() {
    Column() {
      Image($r('app.media.left'))
        ...

      Text($r('app.string.second_second_page_name'))
        ...

      Text(`${this.src}:${this.count}`)
        ...

      // 停止SecondAbility自身并返回结果
      Button($r('app.string.terminate_second_for_result_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
        ...
    }
    ...
  }
}

3.在EntryAbility的Index页面中,点击“导航到SecondAbility的Second Page”按钮后,调用ButtonClickMethod类中的toSecondAbilitySecond方法,拉起SecondAbility的Second页面。

  • 使用UIAbilityContext.startAbilityForResult来实现,并获取被拉起侧销毁后的返回结果。可以通过parameters来向被拉起方传递参数,示例代码如下:
// 导航到SecondAbility的Second Page
toSecondAbilitySecond(context: common.UIAbilityContext, callback: (abilityResult: common.AbilityResult) => void) {
  let want: Want = {
    'deviceId': '',
    'bundleName': CommonConstants.BUNDLE_NAME,
    'abilityName': CommonConstants.SECOND_ABILITY_NAME,
    'moduleName': CommonConstants.DEVICE_MODULE_NAME,
    'parameters': {
       url: 'pages/Second',
       src: textMessage,
       count: CommonConstants.NUM_VALUES[2]
     }
  };

  // 被拉起侧销毁后,在startAbilityForResult回调中可以获取到被拉起侧销毁时传递过来的AbilityResult
  context.startAbilityForResult(want).then((result) => {
    callback(result);
    Logger.info(CommonConstants.TAG, `start second ability second page succeed with ${JSON.stringify(want)}`);
  }).catch((error: Error) => {
    Logger.error(CommonConstants.TAG, `start second ability second page failed with ${error}`);
  });
}
  • 在“Project”窗口,点击“device > src > main > ets > SecondAbility”,打开“SecondAbility.ets”文件,在onWindowStageCreate的生命周期回调函数中获取拉起方的意图,展示SecondAbility的指定页面到界面。示例代码如下:
onWindowStageCreate(windowStage: Window.WindowStage) {
  ...
  let parameters: Record<string, Object> = (GlobalContext.getContext().getObject('secondAbilityWant') as Want)?.parameters as Record<string, Object>;
  let url = parameters?.url ?
    parameters.url as string : 'pages/Index';
  windowStage.loadContent(url, (err, data) => {
    ...
  });
}

4.在SecondAbility的Second页面,点击“停止SecondAbility自身并返回结果”按钮,使用UIAbilityContext.terminateSelfWithResult方法,传入不同的resultCode和want,手动销毁Ability。成功后发起拉起侧会收到abilityResult的值。示例代码如下:

// 停止SecondAbility自身并返回结果
terminateSecondAbilityForResult(context: common.UIAbilityContext) {
  let abilityResult: common.AbilityResult = {
    resultCode: CommonConstants.RESULT_CODE,
    want: {
      'deviceId': '',
      'bundleName': CommonConstants.BUNDLE_NAME,
      'abilityName': CommonConstants.SECOND_ABILITY_NAME,
      'moduleName': CommonConstants.DEVICE_MODULE_NAME,
      'parameters': {
         src: returnMessage,
         count: CommonConstants.RESULT_NUM_VALUE
       }
    }
  };

  // 停止SecondAbility自身,并将abilityResult返回给startAbilityForResult接口调用方
  context.terminateSelfWithResult(abilityResult).then(() => {
    Logger.info(CommonConstants.TAG, `terminate second ability self with
      result succeed with ${JSON.stringify(abilityResult)}`);
  }).catch((error: Error) => {
    Logger.error(CommonConstants.TAG, `terminate second ability self with
      result failed with ${error}`);
  });
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 如何使用Text文本组件。
  2. 如何使用Button按钮组件。
  3. 如何实现UIAbility内页面的跳转。
  4. 跳转到指定UIAbility的首页。
  5. 跳转到指定UIAbility的指定页面(非首页)。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等.....视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF》

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. ……

二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全
  5. ........

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册》

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

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

相关文章

新数据显示,寻求博士后职位的美国科学家越来越少

戈罗登科夫/盖蒂图片社 美国国家科学基金会&#xff08;NSF&#xff09;发布的新数据显示&#xff0c;美国公民从事博士后工作的人数急剧下降&#xff0c;特别是在生物和生物医学科学领域。这一趋势凸显了人们对学术界正面临博士后短缺的担忧&#xff0c;以及早期职业科学家越来…

PPP、RRE、MGRE综合实验

一、实验拓扑图 二、实验要求 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址&#xff1b; 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方: R2与R5之间使用ppp的CHAP认证&#xff0c; R5为主认证方;R3与R5之间使用HDLC封装; 3.R1、R2、…

Python:执行py命令,提示: Can‘t find a default Python.

1.Python运行环境罢工 今天&#xff0c;要运行一个前年用python编写的爬虫程序&#xff0c;先检测python运行环境是否正常&#xff1a; D:\Python38-32\works>c:\windows\py.exe Cant find a default Python. 再试&#xff1a; D:\Python38-32\works>py --list Installe…

Keepalived+MySQL简单搭建实现数据库高可用

需求&#xff1a;想要实现当MySQL服务挂了之后&#xff0c;能够自动切换到另一台&#xff0c;不对当前服务造成过多影响。查找了很多实现数据库高可用方案&#xff0c;比较常见的有MHA&#xff08;至少三台&#xff0c;一主多从&#xff09;、开源数据库中间件&#xff08;Myca…

浅试Kimi

最近KIMI大模型挺火的&#xff0c;擅长处理中文文本&#xff0c;咱也来试试吧&#xff01; 测试问题&#xff1a; 写一篇800字以上的短片小说&#xff1a;主要故事是以一位上进但其他方面表现平平的大男孩小贱&#xff0c;刚到公司不久&#xff0c;就被一位名叫大弟的女同事看…

量化交易入门(二十八)什么是布林带,量化中怎么使用

什么叫布林带 布林带&#xff08;Bollinger Bands&#xff09;是一种常用的技术分析指标&#xff0c;由约翰布林&#xff08;John Bollinger&#xff09;于20世纪80年代开发。它由三条线组成&#xff1a;中轨&#xff08;通常为20日移动平均线&#xff09;、上轨&#xff08;中…

python编程软件有什么

Python开发软件可根据其用途不同分为两种&#xff0c;一种是Python代码编辑器&#xff0c;一种是Python集成开发工具&#xff0c;两者的配合使用可以极大的提高Python开发人员的编程效率&#xff0c;以下是常用的几款Python代码编辑器和Python集成开发工具。 一、Python代码编…

嵌入式linux学习之交叉编译器安装

交叉编译器介绍 ARM 裸机、Uboot 移植、Linux 移植这些都需要在 Ubuntu 下进行编译&#xff0c;编译就需要编译器&#xff0c;在 Liux 进行 C 语言开发里面使用 GCC 编译器进行代码编译&#xff0c;但是 Ubuntu 自带的 gcc 编译器是针对 X86 架构的&#xff01;而我们现在要编…

深入理解Java接口:定义、使用与重要性(day13)

导语&#xff1a;Java接口是Java编程语言中的一个核心概念&#xff0c;它提供了一种定义方法但不包含方法实现的方式。接口在Java编程中扮演着重要角色&#xff0c;能够帮助我们实现代码的高内聚、低耦合&#xff0c;提高代码的复用性和可维护性。本文将详细介绍Java接口的定义…

python练习四

1. 求一个十进制的数值的二进制的0、1的个数 def count_binary_ones(n):binary_str bin(n)[2:] # 转换为二进制字符串&#xff0c;去除前缀0bprint(f"{n} 的二进制为: {binary_str}")return binary_str.count(0), binary_str.count(1) n int(input("输入一个…

Python车道线偏离预警

程序示例精选 Python车道线偏离预警 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《Python车道线偏离预警》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学习与应用推…

memcached缓存数据库简介

memcached是一套分布式的高速缓存系统&#xff0c;由LiveJournal的Brad Fitzpatrick开发&#xff0c;但被许多网站使用。这是一套开放源代码软件&#xff0c;以BSD license授权发布。 memcached缺乏认证以及安全管制&#xff0c;这代表应该将memcached服务器放置在防火墙后。 …

自建机房私有云吗?

大家好&#xff0c;我是小码哥&#xff0c;之前一种有没搞清楚公有云、私有云的概念&#xff0c;今天算是弄清楚了&#xff0c;这里给大家分享一下公有云、私有云的区别&#xff0c;以及自建机房算不算私有云&#xff01; 其实私有云&#xff08;Private Cloud&#xff09;和公…

快排(六大排序)

快速排序 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所…

个人简历主页搭建系列-05:部署至 Github

前面只是本地成功部署网站&#xff0c;网站运行的时候我们可以通过 localhost: port 进行访问。不过其他人是无法访问我们本机部署的网站的。 接下来通过 Github Pages 服务把网站部署上去&#xff0c;这样大家都可以通过特定域名访问我的网站了&#xff01; 创建要部署的仓库…

Spring 源码调试错误修复

Spring 源码调试错误修复 文章目录 Spring 源码调试错误修复1. fatal: not a git repository (or any of the parent directories): .git问题描述解决方案 2. fatal: Needed a single revision问题描述解决方案 1. fatal: not a git repository (or any of the parent director…

14.Java为什么这么火、Java主要特性

文章目录 一、Java为什么这么火&#xff1f;二、Java主要特性 一、Java为什么这么火&#xff1f; 一个语言火不火、能不能长久的生存下去&#xff0c;主要其实是看四个方面 1、用户量&#xff1a;使用的程序员多不多。 不管在国内&#xff0c;还是在国外&#xff0c;使用Jav…

ASCII查询

最近踩的字符坑有点多&#xff0c;自己写了个ASCII查询&#xff0c;不用求人了。 <html> <head> <title>ASCII码查询</title> <style> table { border-collapse:collapse; } th, td { border:1px solid black; padding:10px; text-align:center;…

Java基础之算数运算符的初级用法

运算符 运算符: 对字面量或者变量进行操作的符号 表达式: 用运算符把字面量或者变量连接起来,符合java语法的式子就可以称为表达式 不同运算符连接的表达式体现的是不同类型的表达式 一 .算数运算符 实践一下 加 减 乘 运行结果: 除 取模 运行结果 练习: 数值拆分 需求…

Doris实践——叮咚买菜基于OLAP引擎的应用实践

目录 前言 一、业务需求 二、选型与对比 三、架构体系 四、应用实践 4.1 实时数据分析 4.2 B端业务查询取数 4.3 标签系统 4.4 BI看板 4.5 OLAP多维分析 五、优化经验 六、总结 原文大佬介绍的这篇Doris数仓建设实践有借鉴意义的&#xff0c;这些摘抄下来用作沉淀学…
最新文章