context-userguide.md 11.8 KB
Newer Older
1
# 应用上下文Context使用指导
X
xuzhihao 已提交
2 3 4

## Context概述

U
unknown 已提交
5
​        Context是应用中对象的上下文,提供获取应用程序环境信息的能力。
X
xuzhihao 已提交
6

U
unknown 已提交
7
​        OpenHarmony的应用框架分为FA模型和Stage两种模型。对应存在两套Context机制适配两种应用框架模型,其中application/BaseContext属于通用的Context基类,里面包含一个属性stageMode,用来区分开发模型是FA还是Stage。
X
xuzhihao 已提交
8

9
- FA模型  
10
  只有app/Context中的方法属于FA模型对应的Context。该模式下,应用级别的Context和Ability级别的Context都是该类型的实例,如果在应用级别的Context里面调用了Ability级别的方法,会产生错误。所以开发者需要注意Context实例所代表的实际含义。
X
xuzhihao 已提交
11

12
- Stage模型  
U
unknown 已提交
13
  除了app/Context之外的Context都属于Stage模型,分别有application/Context、application/ApplicationContext、application/AbilityStageContext、application/ExtensionContext、application/AbilityContext、application/FormExtensionContext等Context。这些Context的介绍及使用方式将会在[Stage模型的Context详细介绍](#stage模型的context详细介绍)中进行说明。
X
xuzhihao 已提交
14

U
unknown 已提交
15
![contextIntroduction](figures/contextIntroduction.png)
X
xuzhihao 已提交
16 17 18 19 20 21 22

## FA模型的Context详细介绍

​        只有app/Context中的方法属于FA模型对应的Context。

​        FA模型只有一个Context定义。Context中所有的功能都是通过方法来提供的,它提供了一些featureAbility中不存在的方法,相当于featureAbility的一个扩展和补全。

R
RayShih 已提交
23
**d.ts声明**
X
xuzhihao 已提交
24 25 26

​        https://gitee.com/openharmony/interface_sdk-js/blob/master/api/app/context.d.ts

R
RayShih 已提交
27
**示例**
X
xuzhihao 已提交
28 29 30 31 32

```javascript
import featureAbility from '@ohos.ability.featureAbility'
export default {
  onCreate() {
U
unknown 已提交
33
    // 获取context并调用相关方法
X
xuzhihao 已提交
34
    let context = featureAbility.getContext();
U
unknown 已提交
35 36
    context.getBundleName((data, bundleName)=>{
      console.info("ability bundleName:" + bundleName)
X
xuzhihao 已提交
37
    });
U
unknown 已提交
38
    console.info('Application onCreate')
X
xuzhihao 已提交
39 40
  },
  onDestroy() {
U
unknown 已提交
41
    console.info('Application onDestroy')
X
xuzhihao 已提交
42 43 44 45
  },
}
```

A
altay 已提交
46 47 48 49 50 51 52 53 54 55 56
### FA模型Context常用方法介绍
方法:
```javascript
setDisplayOrientation(orientation: bundle.DisplayOrientation, callback: AsyncCallback<void>): void
setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise<void>;
```
简介:设置当前ability的显示方向。

示例:
```javascript
import featureAbility from '@ohos.ability.featureAbility'
U
unknown 已提交
57
import bundle from '@ohos.bundle';
A
altay 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

export default {
  onCreate() {
    // 获取context并调用相关方法
    let context = featureAbility.getContext();
    context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => {
        console.log("Set display orientation.")
    })
    console.info('Application onCreate')
  },
  onDestroy() {
    console.info('Application onDestroy')
  },
}
```

U
unknown 已提交
74
## Stage模型的Context详细介绍
X
xuzhihao 已提交
75

U
unknown 已提交
76
​        Stage模型有如下几类Context:
X
xuzhihao 已提交
77 78 79

### application/Context

U
unknown 已提交
80
​        application/Context是基类Context。里面提供了应用的一些基础信息:resourceManager、applicationInfo、cacheDir、area等,还有应用的一些基本方法:createModuleContext等。
X
xuzhihao 已提交
81 82 83 84 85

**d.ts声明**

​        https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/Context.d.ts

86 87 88 89 90 91 92 93 94 95 96
### application/ApplicationContext

​         application/ApplicationContext是应用级别的Context。和基类Context相比,应用级别的Context中提供了监听进程内组件的生命周期的能力,包括registerAbilityLifecycleCallback和unregisterAbilityLifecycleCallback两种方法。

**获取方法**

​        在Ability中通过context.getApplicationContext()方法获取。

**示例**

```javascript
D
dy_study 已提交
97
import Ability from "@ohos.application.Ability";
98 99 100

var lifecycleid;

D
dy_study 已提交
101
export default class MainAbility extends Ability {
102
    onCreate() {
D
dy_study 已提交
103
        console.log("MainAbility onCreate")
104 105 106 107
        let AbilityLifecycleCallback  =  {
            onAbilityCreate(ability){
                console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability));        
            },
D
dy_study 已提交
108 109 110
            onWindowStageCreate(ability, windowStage){
                console.log("AbilityLifecycleCallback onWindowStageCreate ability:" + JSON.stringify(ability)); 
                console.log("AbilityLifecycleCallback onWindowStageCreate windowStage:" + JSON.stringify(windowStage));           
111
            },
D
dy_study 已提交
112 113 114 115 116 117 118 119 120 121 122
            onWindowStageActive(ability, windowStage){
                console.log("AbilityLifecycleCallback onWindowStageActive ability:" + JSON.stringify(ability)); 
                console.log("AbilityLifecycleCallback onWindowStageActive windowStage:" + JSON.stringify(windowStage));           
            },
            onWindowStageInactive(ability, windowStage){
                console.log("AbilityLifecycleCallback onWindowStageInactive ability:" + JSON.stringify(ability));
                console.log("AbilityLifecycleCallback onWindowStageInactive windowStage:" + JSON.stringify(windowStage));  
            },
            onWindowStageDestroy(ability, windowStage){
                console.log("AbilityLifecycleCallback onWindowStageDestroy ability:" + JSON.stringify(ability));
                console.log("AbilityLifecycleCallback onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));  
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
            },
            onAbilityDestroy(ability){
                console.log("AbilityLifecycleCallback onAbilityDestroy ability:" + JSON.stringify(ability));             
            },
            onAbilityForeground(ability){
                console.log("AbilityLifecycleCallback onAbilityForeground ability:" + JSON.stringify(ability));             
            },
            onAbilityBackground(ability){
                console.log("AbilityLifecycleCallback onAbilityBackground ability:" + JSON.stringify(ability));              
            },
            onAbilityContinue(ability){
                console.log("AbilityLifecycleCallback onAbilityContinue ability:" + JSON.stringify(ability));
            }
        }
        // 1.通过context属性获取applicationContext
        let applicationContext = this.context.getApplicationContext();
        // 2.通过applicationContext注册监听应用内生命周期
        lifecycleid = applicationContext.registerAbilityLifecycleCallback(AbilityLifecycleCallback);
        console.log("registerAbilityLifecycleCallback number: " + JSON.stringify(lifecycleid));       
D
dy_study 已提交
142
    },
143 144 145
    onDestroy() {
        let applicationContext = this.context.getApplicationContext();
        applicationContext.unregisterAbilityLifecycleCallback(lifecycleid, (error, data) => {
D
dy_study 已提交
146
            console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error));
147 148 149 150 151 152 153 154 155
        });
    }
}
```

**d.ts声明**

​        https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ApplicationContext.d.ts

X
xuzhihao 已提交
156 157 158 159 160 161
### application/AbilityStageContext

​        application/AbilityStageContext是Hap包级别的Context。和基类Context相比,Hap包级别的Context中多了HapModuleInfo和Configuration两个信息。

**获取方法**

162
​        可以直接在AbilityStage中通过context属性获取。
X
xuzhihao 已提交
163 164 165 166 167 168 169

**示例**

```javascript
export default class MyAbilityStage extends AbilityStage {
  onCreate() {
    // 属性context就是AbilityStageContext类型的
U
unknown 已提交
170
    console.log('HapModuleInfo is ' + this.context.currentHapModuleInfo);
X
xuzhihao 已提交
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
  }
}
```

**d.ts声明**

​        https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityStageContext.d.ts

### application/AbilityContext

​        Stage模型下,每个Ability中都包含了一个Context属性。

​        Ability功能主要是处理生命周期,其余操作Ability的方法(如startAbility、connectAbility等)都是在AbilityContext中实现的。

**获取方法**

187
​        在Ability中通过context属性获取。
X
xuzhihao 已提交
188 189 190 191

**示例**

```javascript
U
unknown 已提交
192 193
import Ability from '@ohos.application.Ability'

X
xuzhihao 已提交
194
export default class MainAbility extends Ability {
U
unknown 已提交
195 196 197
    onCreate(want, launchParam) {
        console.log("[Demo] MainAbility onCreate")
        globalThis.abilityWant = want;
X
xuzhihao 已提交
198 199
    }

U
unknown 已提交
200 201 202
    onDestroy() {
        console.log("[Demo] MainAbility onDestroy")
    }
X
xuzhihao 已提交
203

U
unknown 已提交
204 205 206
    onWindowStageCreate(windowStage) {
        // Main window is created, set main page for this ability
        console.log("[Demo] MainAbility onWindowStageCreate")
X
xuzhihao 已提交
207

U
unknown 已提交
208 209 210
        // 在这里获取AbilityContext,打印ability的信息
        let context = this.context;
        console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName)
X
xuzhihao 已提交
211

U
unknown 已提交
212 213 214 215 216 217 218
        windowStage.loadContent("pages/index", (err, data) => {
            if (err.code) {
                console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data))
        });
U
unknown 已提交
219
    }
X
xuzhihao 已提交
220

U
unknown 已提交
221 222 223 224
    onWindowStageDestroy() {
        // Main window is destroyed, release UI related resources
        console.log("[Demo] MainAbility onWindowStageDestroy")
    }
X
xuzhihao 已提交
225

U
unknown 已提交
226 227 228 229
    onForeground() {
        // Ability has brought to foreground
        console.log("[Demo] MainAbility onForeground")
    }
X
xuzhihao 已提交
230

U
unknown 已提交
231 232 233 234 235
    onBackground() {
        // Ability has back to background
        console.log("[Demo] MainAbility onBackground")
    }
};
X
xuzhihao 已提交
236 237 238 239
```

### application/FormExtensionContext

U
unknown 已提交
240 241
卡片业务相关,点下面链接了解。

Z
zhongjianfei 已提交
242
[FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md)
X
xuzhihao 已提交
243

L
liqiang 已提交
244
### 在ArkTS页面中访问Context
245

L
liqiang 已提交
246
Stage模型下,在Ability的`onWindowStageCreate`生命周期中,可以通过WindowStage的`SetUIContent`方法加载一个ArkTS页面。在一些场景中,需要在页面内获取Context调用相关API。
247 248 249

**获取方法**

L
liqiang 已提交
250
在ArkTS页面中通过以下全局方法获取当前页面关联的Context。
251 252 253 254

| 接口名                                   | 描述                           |
| :------------------------------------ | :--------------------------- |
| getContext(component: Object): Object | 获取页面中component所关联的Context对象。 |
255 256 257

**示例**

258
```ts
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
// MainAbility.ts
import Ability from '@ohos.application.Ability'

export default class MainAbility extends Ability {
    onCreate(want, launchParam) {
        console.log("[Demo] MainAbility onCreate")
    }

    onDestroy() {
        console.log("[Demo] MainAbility onDestroy")
    }

    onWindowStageCreate(windowStage) {
        // 加载index页面,并传入当前Context
        windowStage.setUIContent(this.context, "pages/index", null)
    }

    onWindowStageDestroy() {}

    onForeground() {}

    onBackground() {}
};
```

284
```ts
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
// pages/index.ets
import context from '@ohos.application.context'

type Context = context.Context

@Entry
@Component
struct Index {
    build() {
        Row() {
            Column() {
                Text('GetContext')
                    .fontSize(50)
                    .fontWeight(FontWeight.Bold)
                    .onClick(() => {
                        // 获取当前component关联的Context
                        var context : Context = getContext(this) as Context
                        console.info("CacheDir:" + context.cacheDir)
                    })
            }
            .width('100%')
        }
        .height('100%')
    }
}
```

U
unknown 已提交
312
## 常见错误使用方式
X
xuzhihao 已提交
313

U
unknown 已提交
314
**错误1:Stage模型通过globalThis去获取Context**
X
xuzhihao 已提交
315 316 317

**原因**

U
unknown 已提交
318
​        应用框架在API9上推出了新的应用模型(Stage模型)。在老的模型(FA模型)下,每个Ability实例有一个js虚拟机实例,所以可以从js引擎的global对象上,获取到一个全局的Ability实例,但是在新的模型(Stage模型)下,整个应用进程共用一个js虚拟机实例,其中可以运行多个Ability实例,这样就不存在一个全局的Ability实例。如果开发者在新的模型(Stage模型)下,调用的API实现仍然走到了获取全局Ability实例的方法,就可能会发生错误或者崩溃。