HarmonyOS NEXT智能终端应用开发 课件 第5章 Stage应用开发模型_第1页
HarmonyOS NEXT智能终端应用开发 课件 第5章 Stage应用开发模型_第2页
HarmonyOS NEXT智能终端应用开发 课件 第5章 Stage应用开发模型_第3页
HarmonyOS NEXT智能终端应用开发 课件 第5章 Stage应用开发模型_第4页
HarmonyOS NEXT智能终端应用开发 课件 第5章 Stage应用开发模型_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章Stage应用开发模型在鸿蒙应用程序开发的术语中,应用框架服务称为AbilityKit,AbilityKit为应用程序开发和运行提供了应用模型。目前,鸿蒙AbilityKit提供了两种应用开发模型:Stage应用开发模型和FA应用开发模型。其中,FA应用开发模型,简称FA模型,也就是FeatureAbility模型,从鸿蒙API7开始支持的模型,目前已经不再主推,因此,本章不再介绍FA模型;Stage应用开发模型,简称Stage模型,从鸿蒙API9开始新增的模型,是主推且会长期演进的应用开发模型。由于Stage模型提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种模型为Stage模型。Stage应用开发模型由一系列组件组成,包括:UIAbility、AbilityStage、WindowStage、Context、Want等组件以及配置文件构成。本章对Stage模型的重要组件进行介绍。目录5.1Stage模型概述5.2UIAbility5.3信息传递载体Want对象5.4案例:揭开宝藏5.5练习:图片评论5.1Stage模型概述当新建鸿蒙程序工程时,DevEco会自动为工程创建程序的基本架构,其中包含两个重要的配置文件:app.json5和module.json5。例如,新建一个名为ch0501的鸿蒙程序工程,其工程结构和配置文件如图。当鸿蒙系统启动一个应用程序时,它首先分析应用程序的配置文件,进而根据配置创建应用程序运行环境,实例化相关对象,最后启动应用运行。因此,应用程序的两个配置文件app.json5和module.json5在应用程序中起到了非常重要的作用。5.1.1app.json5配置文件app.json5文件位于应用程序的AppScope目录下。app.json5配置文件的内容如下:{"app":{"bundleName":"com.example.ch0501","vendor":"example","versionCode":1000000,"versionName":"1.0.0","icon":"$media:layered_image","label":"$string:app_name"}}5.1.2module.json5配置文件一个鸿蒙应用程序可以包括一个或者多个模块。例如,新建的ch0501的程序工程只包含一个名称为entry的模块,当然,可以根据需要在程序工程中新建模块。每个模块都包含一个用于对本模块进行说明的配置文件module,json5。对于ch0501程序的entry模块,其配置文件module.json5内容如下:{"module":{"name":"entry","type":"entry","description":"$string:module_desc","mainElement":"EntryAbility","deviceTypes":["phone","tablet","2in1"],"deliveryWithInstall":true,"installationFree":false,"pages":"$profile:main_pages","abilities":[{"name":"EntryAbility","srcEntry":"./ets/entryability/EntryAbility.ets","description":"$string:EntryAbility_desc","icon":"$media:layered_image","label":"$string:EntryAbility_label","startWindowIcon":"$media:startIcon","startWindowBackground":"$color:start_window_background","exported":true,"skills":[{"entities":["entity.system.home"],"actions":["action.system.home"]}]}],"extensionAbilities":[{"name":"EntryBackupAbility","srcEntry":"./ets/entrybackupability/EntryBackupAbility.ets","type":"backup","exported":false,"metadata":[{"name":"ohos.extension.backup","resource":"$profile:backup_config"}],}]}}这些配置属性及其含义如下:name参数指定模块的名字;type参数指定模块的类型,除了可以是entry模块外,还可以是feature模块、har模块、shared模块等;mainElement参数指定应用程序的入口UIAbility类,也就是启动应用时,第一个要显示的UI界面,关于UIAbility将在下一节介绍,它是Stage模型中非常重要的组成组件,一个UIAbility代表一个应用程序的UI界面组件,在这个例子中,指明程序的入口UIAbility类为EntryAbility;pages参数一个文件中,在该文件中以列表的形式指定可以显示在模块中的所有UI页面文件,默认情况下,这个文件是“resources/base/profile/main_pages.json”文件;abilities参数是一个JSON数组,鸿蒙系统规定,应用程序的每个UIAbility类都需要在abilities参数中配置,例如,当前的entry模块中包括了一个名称为EntryAbility的UIAbility。5.2UIAbilityUIAbility是Stage模型的核心组成部分,它是一种包含UI的应用组件,主要用于和用户交互。简单来说,UIAbility为应用程序的UI提供了显示以及与用户进行交互的机制。当用户启动一个应用程序时,鸿蒙系统将分析app.json5和module.json5配置文件,并从配置文件module.json5中找到名字为mainElement配置参数。例如,对于ch0501工程,mainElement配置参数的值是EntryAbility类:它是UIAbility类的子类,如图。5.2.1UIAblity启动过程及其生命周期EntryAbility是UIAbility类的子类,它代表以及管理可以与用户进行交互的UI界面。先观察一下如下所示的EntryAbility.ets的代码:import{AbilityConstant,ConfigurationConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{window}from'@kit.ArkUI';

constDOMAIN=0x0000;exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);(DOMAIN,'testTag','%{public}s','AbilityonCreate');}

onDestroy():void{(DOMAIN,'testTag','%{public}s','AbilityonDestroy');}

onWindowStageCreate(windowStage:window.WindowStage):void{//Mainwindowiscreated,setmainpageforthisability(DOMAIN,'testTag','%{public}s','AbilityonWindowStageCreate');

windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(DOMAIN,'testTag','Failedtoloadthecontent.Cause:%{public}s',JSON.stringify(err));return;}(DOMAIN,'testTag','Succeededinloadingthecontent.');});}

onWindowStageDestroy():void{//Mainwindowisdestroyed,releaseUIrelatedresources(DOMAIN,'testTag','%{public}s','AbilityonWindowStageDestroy');}

onForeground():void{//Abilityhasbroughttoforeground(DOMAIN,'testTag','%{public}s','AbilityonForeground');}

onBackground():void{//Abilityhasbacktobackground(DOMAIN,'testTag','%{public}s','AbilityonBackground');}}观察语句:exportdefaultclassEntryAbilityextendsUIAbility{可以看出,EntryAbility是UIAbility的子类,同时,还可以观察到,在EntryAbility类中,有多个名称类似onXXXX(…)的方法:它们是UIAbility的生命周期方法,鸿蒙系统会在适当的时机调用这些方法从而完成UIAbility的业务功能。那么,鸿蒙系统会在什么时机调用这些名称为onXXX(…)的方法呢?这需要对UIAbility的启动过程有一个了解。鸿蒙系统会依照如下图所示的过程启动EntryAbility运行。hilog日志系统提供了多个方法用于显示信息,其中info()方法用于显示信息级别的消息。()方法的原型是:function(domain:number,tag:string,format:string,...args:any[]):void作用:显示信息级别的消息;5.2.2指定UIAbility显示的UI组件UIAbility为用户与UI交互提供了基础的支撑,但是,具体的UI界面则是存放在独立的称为page的文件中。UIAbility在准好准备后,将显示指定的UI界面。通常的情况是,UIAbility在其生命周期的onWindowStageCreate()方法中指定要显示的UI界面。例如,在ch0501工程的EntryAbility类中,其onWindowStageCreate()方法的代码如下:onWindowStageCreate(windowStage:window.WindowStage):void{//Mainwindowiscreated,setmainpageforthisability(DOMAIN,'testTag','%{public}s','AbilityonWindowStageCreate');

windowStage.loadContent('pages/Index',(err)=>{//加载要显示的页面if(err.code){hilog.error(DOMAIN,'testTag','Failedtoloadthecontent.Cause:%{public}s',JSON.stringify(err));return;}(DOMAIN,'testTag','Succeededinloadingthecontent.');});}在这个生命周期方法中,通过语句:

windowStage.loadContent('pages/Index',(err)=>{加载并显示了entry模块下pages子目录下的Index.ets界面组件。如图所示。其中pages/Index.ets文件就是在第三章已经介绍过的UI组件,这个UI组件显示一个包含“HelloWorld”的文本框,当点击这个而文本框时,显示的文字将变更为“Welcome”。该文件的内容如下:@Entry@ComponentstructIndex{@Statemessage:string='HelloWorld';

build(){RelativeContainer(){Text(this.message).id('HelloWorld').fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).alignRules({center:{anchor:'__container__',align:VerticalAlign.Center},middle:{anchor:'__container__',align:HorizontalAlign.Center}}).onClick(()=>{this.message='Welcome';})}.height('100%').width('100%')}}默认情况下,鸿蒙系统规定,所有可以在UIAbility中显示的UI页面都需要在配置文件“resources/base/profile/main_pages.json”中进行配置,此时如果打开这个文件,将显示如下内容:由于在entry模块中只有一个Index.ets页面,所以,在main_pages.json文件中只有一个UI页面。{"src":["pages/Index"]}5.2.3在UIAbility及其UI页面中获取上下文信息在鸿蒙系统中运行的应用程序都有与之紧密联系的运行环境,习惯上,称这个运行环境为上下文对象,英文名称为Context。通过程序运行的上下文对象,可以获取其他相关信息,或者控制程序的运行行为。一个程序存在多个不同类型的上下文对象,例如,一个正在运行的应用程序有一个上下文,一个正在运行的UIAbility有一个上下文等等。在鸿蒙系统下,根据应用组件的层次不同,存在多个不同的上下文,如图。一个鸿蒙应用程序APP可以包含多个模块,一个模块又包含一个AbilityStage对象和多个UIAbility对象。与应用程序APP关联的是ApplicationContext的上下文对象;与AblityStage对象关联的是AblityStatgeContext上下文对象;与UIAbility关联的是UIAbilityContext对象。1、在UIAbility中获取UIAbilityContext对象在UIAbility中,可以直接通过this.context获取UIAbility实例的上下文信息。例如,对于ch0501的EntryAbility,可以在onCreate()生命周期方法中获得UIAbilityContext对象,并显示相关信息。修改后的EnrtyAbility代码如下:import{AbilityConstant,ConfigurationConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{window}from'@kit.ArkUI';

import{common}from'@kit.AbilityKit'//导入需要的模块

constDOMAIN=0x0000;

exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);(DOMAIN,'testTag','%{public}s','AbilityonCreate');

letcontext:common.UIAbilityContext=this.context;(DOMAIN,'testTag','%{public}s',context.abilityInfo.bundleName);(DOMAIN,'testTag','%{public}s',context.config.language);(DOMAIN,'testTag','%{public}s',context.filesDir);}

onDestroy():void{(DOMAIN,'testTag','%{public}s','AbilityonDestroy');}

onWindowStageCreate(windowStage:window.WindowStage):void{//Mainwindowiscreated,setmainpageforthisability(DOMAIN,'testTag','%{public}s','AbilityonWindowStageCreate');

windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(DOMAIN,'testTag','Failedtoloadthecontent.Cause:%{public}s',JSON.stringify(err));return;}(DOMAIN,'testTag','Succeededinloadingthecontent.');});}

onWindowStageDestroy():void{//Mainwindowisdestroyed,releaseUIrelatedresources(DOMAIN,'testTag','%{public}s','AbilityonWindowStageDestroy');}

onForeground():void{//Abilityhasbroughttoforeground(DOMAIN,'testTag','%{public}s','AbilityonForeground');}

onBackground():void{//Abilityhasbacktobackground(DOMAIN,'testTag','%{public}s','AbilityonBackground');}}运行这个程序。2、在页面中获取UIAbilityContext对象除了可以在UIAbility的子类中获取UIAbilityContext外,还可以在页面程序中获取UIAbilityContext对象。修改页面Index.ets代码为如下内容:import{common,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';

constDOMAIN=0x0000;

@Entry@ComponentstructIndex{@Statemessage:string='HelloWorld';privatecontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;

build(){RelativeContainer(){Text(this.message).id('HelloWorld').fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).alignRules({center:{anchor:'__container__',align:VerticalAlign.Center},middle:{anchor:'__container__',align:HorizontalAlign.Center}}).onClick(()=>{this.message='Welcome';(DOMAIN,'testTag','%{public}s',this.context.abilityInfo.bundleName);})}.height('100%').width('100%')}}使用语句:

privatecontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;获得了UIAbilityContext对象,进而在文本框的onClick事件处理程序中使用语句:

(DOMAIN,'testTag','%{public}s',this.context.abilityInfo.bundleName);显示UIAbilityContext对象的属性信息。5.2.4UIAbility组件启动模式模块配置文件module.json5中,针对UIAbility的配置选项中有一个配置UIAbility启动模式的配置选项“launchType”。这个配置选项可以设置一下三个不同的值:其一,singleton,称为单实例模式,也是默认情况下的启动模式。当每次启动launchType设置为singleton的UIAbility时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。其二,multiton,称为多实例模式。当每次启动launchType设置为multiton的UIAbility时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。standard是multiton的曾用名,效果与多实例模式一致。其三,specified,称为指定实例模式。针对一些特殊场景使用,例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已经存在的文档希望打开的都是同一个文档实例等,在这种特殊的情况下使用specified启动模式。5.3信息传递载体Want对象Want是一种对象,用于在应用组件之间传递信息。它是鸿蒙应用程序各个部件之间联系的桥梁和纽带。5.3.1使用Want实现UIAbility之间的跳转Want对象的一种常见的使用场景是实现UIAbility之间的跳转,例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。下面就以这样的需求场景为例,介绍Want的使用。在DevEco中新建一个名称为ch0502的工程,在新建的工程中已经存在了一个名称为EntryAbility的UIAbility。现在新建一个名称为UIAblityB的UIAbility,如图。在弹出的界面的“Abilityname”中输入“UIAbilityB”,然后点击“Finish”按钮创建UIAbilityB及其目录,如图。新建的UIAbilityB是UIAbility的子类,并且也将显示pages/Index页面,但是由于pages/Index是被EntryAbility显示的页面。为了不至于混淆,为UIAbilityB新建一个属于自己的页面:Second。修改Second.ets代码为如下内容:将UIAbilityB.ets中显示pages/Index页面的修改为显示pages/Second@Entry@ComponentstructSecond{@Statemessage:string='你好,世界!;

build(){RelativeContainer(){Text(this.message).id('SecondHelloWorld').fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).alignRules({center:{anchor:'__container__',align:VerticalAlign.Center},middle:{anchor:'__container__',align:HorizontalAlign.Center}}).onClick(()=>{this.message='欢迎你的到来';})}.height('100%').width('100%')}}修改Index.ets代码,使得当用户点击“Hello,World”文本框时,将启动UIAbilityB运行,也就是,将显示UIAbilityB所指定显示的页面。修改后的Index.ets代码如下:import{common,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';

@Entry@ComponentstructIndex{@Statemessage:string='HelloWorld';privatecontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;

build(){RelativeContainer(){Text(this.message).id('HelloWorld').fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).alignRules({center:{anchor:'__container__',align:VerticalAlign.Center},middle:{anchor:'__container__',align:HorizontalAlign.Center}}).onClick(()=>{letwant:Want={deviceId:'',//deviceId为空表示本设备bundleName:'com.example.ch0502',abilityName:'UIAbilityB',}this.context.startAbility(want);})}.height('100%').width('100%')}}运行这个程序,将显示首界面,点击“Hello,World”文本框,将启动UIAbilityB运行。在ch0502程序中,已经有两个UIAbility:EntryAbility和UIAbilityB,现在查看一下模块配置module.json5,将看到对这两个Ability的配置信息。由于在UIAbilityB中,显示了页面Second.ets,现在打开“resources/base/profile/main_pages.json”文件,其内容如下:{"src":["pages/Index","pages/Second"]}5.3.2显式Want和隐式Want应用程序组件之间可以使用Want对象来指定要启动的UIAbility。例如,在5.3.1节中,Entrybility使用如下所示的代码启动了UIAbilityB:在这个Want对象中,程序代码通过Want的属性bundleName、abilityName明确指明了要打开的UIAbility,然后再使用context的startAbility()打开UIAbility。这种明确指明要启动某个具体UIAbility的方式称为显式Want。显式Want采用如下表所示的规则来匹配和启动UIAbility。letwant:Want={deviceId:'',//deviceId为空表示本设备bundleName:'com.example.ch0502',abilityName:'UIAbilityB',}this.context.startAbility(want);序号属性名称类型匹配项必选匹配规则1deviceIdstring是否留空将仅匹配本设备内的应用组件2bundleNamestring是是应用程序名称。必须要指定,如果指定abilityName,而不指定bundleName,则匹配失败3moduleNamestring是否匹配对应Module内的目标应用组件。留空时当同一个应用内存在多个模块且模块间存在重名应用组件,将默认匹配第一个4abilityNamestring是是指定要启动的UIAbility,该字段必须设置表示显式匹配除了显式Want打开目标UIAbility外,鸿蒙系统也支持通过隐式Want方式指明要打开的UIAbility。所谓隐式Want,就是“含蓄”地指出目标UIAbility所应该具备的“能力”进而打开指定的UIAbility。较为常用的隐式Want是指出目标UIAbility所需要支持的action属性和entities属性:其一,在Want对象内指明action字段,表示希望目标UIAbility应支持的action操作,并在目标UIAbility的应用配置文件的skills字段内声明actions属性,表示该应用支持的操作列表;其二,在Want对象内指明entities字段,表示希望目标UIAbility应用所属的类别,并在目标UIAbility的应用配置文件的skills字段内声明entites属性,表示该应用支持的类别。看一个使用隐式Want打开UIAbility的例子。在ch0502例子程序的主页面Index.ets中,在文本框“Hello,World”下新增一个显式文字“隐式Want”的按钮,点击这个按钮,以隐式方式打开UIAbilityB。修改后的Index.ets文件如下:import{common,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';

@Entry@ComponentstructIndex{@Statemessage:string='HelloWorld';privatecontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;build(){Column(){Text(this.message).id('HelloWorld').margin({top:40}).fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).onClick(()=>{letwant:Want={deviceId:'',//deviceId为空表示本设备bundleName:'com.example.ch0502',abilityName:'UIAbilityB',}this.context.startAbility(want);})Button("隐式Want").fontSize(25).margin(30).width('100%').onClick(()=>{letwant:Want={deviceId:'',//deviceId为空表示本设备action:'com.example.ch0502.uib',entities:['com.example.ch0502.entityb']}this.context.startAbility(want);})}.height('100%').width('100%')}}通过action属性和entities属性指明目标UIAbility需要支持的“能力”。在这个例子中指明:如果目标UIAbility的action包含“com.example.ch0502.uib”,同时entities包含“com.example.ch0502.entityb”,那么,这个Want对象就可以打开这个UIAbility。可是,UIAbility的action、entities在哪里配置呢?在module.json5中配置。修改module.json5文件,配置UIABilityB的能力,修改后的文件内容如下:{"module":{"name":"entry","type":"entry","description":"$string:module_desc","mainElement":"EntryAbility","deviceTypes":["phone","tablet","2in1"],"deliveryWithInstall":true,"installationFree":false,"pages":"$profile:main_pages","abilities":[{"name":"EntryAbility","srcEntry":"./ets/entryability/EntryAbility.ets","description":"$string:EntryAbility_desc","icon":"$media:layered_image","label":"$string:EntryAbility_label","startWindowIcon":"$media:startIcon","startWindowBackground":"$color:start_window_background","exported":true,"skills":[{"entities":["entity.system.home"],"actions":["action.system.home"]}]},{"name":"UIAbilityB","srcEntry":"./ets/uiabilityb/UIAbilityB.ets","description":"$string:UIAbilityB_desc","icon":"$media:layered_image","label":"$string:UIAbilityB_label","startWindowIcon":"$media:startIcon","startWindowBackground":"$color:start_window_background","skills":[{"entities":["com.example.ch0502.entityb"],"actions":["com.example.ch0502.uib"]}]}],"extensionAbilities":[{"name":"EntryBackupAbility","srcEntry":"./ets/entrybackupability/EntryBackupAbility.ets","type":"backup","exported":false,"metadata":[{"name":"ohos.extension.backup","resource":"$profile:backup_config"}],}]}}在UIAbilityB的配置项中,增加了对UIAbilityB的skills属性的配置,其中增加了UIAbilityB所支持的action和entities。这种隐含地指明要启动某个UIAbility的方式称为隐式Want。隐式Want采用如下表所示的规则来匹配和启动UIAbility。序号属性名称类型匹配项必选匹配规则1deviceIdstring是否跨设备目前不支持隐式调用2bundleNamestring是否匹配对应应用包内的目标应用组件3moduleNamestring是否匹配对应Module内的目标应用组件4abilityNamestring否否该字段必须留空表示隐式匹配5uristring是否Want对象中的uri属性以形如“scheme://host:port/path”的字符串定义,匹配UIAbility的skills中的uris属性,uris属性格式举例如下:uris:[‘scheme’:‘http’,‘host’:‘’,‘port’:8080,‘path’:‘data/add’,‘type’:‘text/plain’]6typestring是否Want对象的type属性值必须匹配UIAbility配置中的skills的uris的type属性值。这里的type的值都是MIME值,例如“text/plain”、“image/png”等7actionstring是否Want对象的action属性值必须包含在UIAbility配置的skills的action列表中8entitiesArray<string>是否Want对象的entities属性值必须包含在UIAbility配置的skills的entities列表中9parameters{linkFeature:Object}是否当前支持使用key为linkFeature的参数进行匹配,当linkFeature字段取值不为空时,优先进行linkFeature匹配5.3.3特殊含义的action值和entities值在隐式Want方式中,有一个具有特殊含义的action和一个具有特殊含义的entities:它们分别是“action.system.home”和“entity.system.home”。当action值“action.system.home”和entities值“entity.system.home”配合使用时,指明当用户在桌面上点击应用程序时,鸿蒙系统将打开指定的UIAbility作为应用程序的启动界面。5.3.4传递参数到目标UIAbility并获取返回结果不论是使用显式Want还是隐式Want启动目标UIAbility,可能都需要向目标UIAbility传递一些参数,或者还需要接收目标UIAbility的执行结果。一个典型的场景是在应用中将主体业务功能和用户账号登录功能分别设计为两个独立的UIAbility,在账号登录UIAbility中完成登录操作后,需要将登录的结果返回给主体业务功能UIAbility。在这种情况下,需要调用方使用context的startAbilityForResult()方法启动目标UIAbility。下面举个例子说明如何向目标UIAbility传递参数以及如何接收目标UIAbility的返回的结果。这个例子在入口EntryAbility上显示一个输入框、一个按钮,点击按钮将打开名称为UIAbilityImage的新的UIAbility界面,并将在EntryAbility输入框中输入的文字信息传递到UIAbilityImage中。UIAbilityImage将显示从EntryAbility传递的信息,同时显示两张图片。点击任何一张将关闭UIAbilityImage界面并返回点击的图片编号到EntryAbility中。为此,新建名称为ch0503的鸿蒙工程,并修改Index.ets页面为如下内容:import{common,Want}from'@kit.AbilityKit';import{BusinessError}from'@kit.BasicServicesKit';

constRESULT_CODE:number=1001;

@Entry@ComponentstructIndex{@Statetext:string='';@Stateanswer:string='Hello';privatecontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;

build(){Column({space:20}){TextInput({text:$$this.text,placeholder:'inputyourword...'}).fontSize(20).margin(10).placeholderColor(Color.Grey).placeholderFont({size:20,weight:400}).caretColor(Color.Blue).width('100%').height(40)Button('显示图片').width('100%').margin(10).onClick(()=>{letwant:Want={deviceId:'',//deviceId为空表示本设备bundleName:'com.example.ch0503',abilityName:'UIAbilityImage',parameters:{message:this.text}}this.context.startAbilityForResult(want).then((data)=>{if(data?.resultCode===RESULT_CODE){//解析被调用方UIAbility返回的信息letback=data.want?.parameters?.answer;if(back!==null){this.getUIContext().getPromptAction().showToast({message:JSON.stringify(back)});this.answer=back?.toString()||'';}}}).catch((err:BusinessError)=>{this.getUIContext().getPromptAction().showToast({message:'ERROR:'+err.message});});})Text(this.answer).fontSize(30).margin(10)}.width('100%').height('100%').justifyContent(FlexAlign.Center)}}现在新建名称为UIAbilityImage的UIAbility类,为此,右击ets目录,选择newAblity,在弹出的窗口中的“Abilityname”输入框中输入UIAbilityImage,然后点击“Finish”按钮。修改新建的UIAbilityImage为如下内容:import{AbilityConstant,UIAbility,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{window}from'@kit.ArkUI';

constDOMAIN=0x0000;

exportdefaultclassUIAbilityImageextendsUIAbility{privatemessage:string='';

onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{this.message=want.parameters?.message?.toString()||'';AppStorage.setOrCreate('message',this.message);(DOMAIN,'testTag','%{public}s','AbilityonCreate');}

onDestroy():void{(DOMAIN,'testTag','%{public}s','AbilityonDestroy');}onWindowStageCreate(windowStage:window.WindowStage):void{//Mainwindowiscreated,setmainpageforthisability(DOMAIN,'testTag','%{public}s','AbilityonWindowStageCreate');

windowStage.loadContent('pages/Images',(err)=>{if(err.code){hilog.error(DOMAIN,'testTag','Failedtoloadthecontent.Cause:%{public}s',JSON.stringify(err));return;}(DOMAIN,'testTag','Succeededinloadingthecontent.');});}

onWindowStageDestroy():void{//Mainwindowisdestroyed,releaseUIrelatedresources(DOMAIN,'testTag','%{public}s','AbilityonWindowStageDestroy');}

onForeground():void{//Abilityhasbroughttoforeground(DOMAIN,'testTag','%{public}s','AbilityonForeground');}

onBackground():void{//Abilityhasbacktobackground(DOMAIN,'testTag','%{public}s','AbilityonBackground');}}新建并修改Images.ets为如下内容:import{common}from'@kit.AbilityKit';

constRESULT_CODE:number=1001;

@Entry@ComponentstructImages{@StorageLink('message')message:string='';

build(){Column(){Text(this.message).fontSize(30).margin(10).fontWeight(FontWeight.Bold)Image('images/a01.jpg').width('100%').height(200).margin(5).onClick(()=>{letcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;//UIAbilityContextletabilityResult:common.AbilityResult={resultCode:RESULT_CODE,want:{bundleName:'com.example.ch0503',moduleName:'entry',//moduleName非必选abilityName:'UIAbilityImage',parameters:{answer:'NO.1'},},};context.terminateSelfWithResult(abilityResult,(err)=>{if(err.code){this.getUIContext().getPromptAction().showToast({message:JSON.stringify(err.message)});return;}});})Image('images/a02.jpg').width('100%').height(200).margin(5).onClick(()=>{letcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;//UIAbilityContextletabilityResult:common.AbilityResult={resultCode:RESULT_CODE,want:{bundleName:'com.example.ch0503',moduleName:'entry',//moduleName非必选abilityName:'UIAbilityImage',parameters:{answer:'NO.2'},},};context.terminateSelfWithResult(abilityResult,(err)=>{if(err.code){this.getUIContext().getPromptAction().showToast({message:JSON.stringify(err.message)});return;}});})}.height('100%').width('100%')}}因为Images.ets页面需要显示图片,因此,在ets目录下新建images子目录,并放置名称为a01.jpg和a02.jpg的图片。完整的ch0503工程结果如图。运行这个程序。5.4案例:揭开宝藏通过Want在UIAbility之间传递信息,以及通过Want从一个UIAbility打开另一个UIAbility是鸿蒙应用程序的Stage架构的重要内容。本节通过一个案例再次演示UIAbility以及Want的应用。5.4.1案例目标设计一个鸿蒙应用程序,在程序的主界面显示一个代表秘密的图片和一个按钮,点击按钮将显示另一个界面,在新的界面中用户可以输入一个开启秘密的密码,如果密码正确则将替换主界面的图片为一张新的表示宝藏的图片。5.4.2案例分析在EntryAbility中显示表示秘密的图片,当用户点击按钮时,通过Want对象打开一个新的名称为PassportAbility的UIAbility,在这个界面中,用户输入密码,如果输入的密码正确,则返回宝藏图片资源给EntryAbility,然后,EntryAbility将界面上的图片替换为宝藏图片。从以上分析可以看出,需要设计如下代码:1、 EntryAbility.ets:入口主界面,加载并显示Index.ets页面内容;2、 Index.ets:入口UI页面,其中显示一张图片和一个按钮;3、 PassportAbility.ets:验证用户输入密码的UIAblity,加载并显示Passport.ets页面;4、 Passport.ets:显示一个输入文本框的页面,允许用户输入密码。5.4.3案例实施在DevEco中新建一个名称为ch0504的鸿蒙程序工程,在工程ets目录下新建images目录,并在其中放置代表秘密和宝藏的图片。完成后的工程结果如图。对于EntryAbility.ets代码,由于该代码文件已经由DevEco在创建工程时生成,并且无需做任何修改。下面修改Index.ets页面文件,在其中显示一张图片和一个按钮,修改后的代码如下:impor

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论