提交 7570cfb0 编写于 作者: E ester.zhou

Update docs (19063)

Signed-off-by: Nester.zhou <ester.zhou@huawei.com>
上级 66f334bf
......@@ -63,42 +63,6 @@ struct WebComponent {
Implements a **WebMessagePort** object to send and receive messages.
### close
close(): void
Closes this message port.
**System capability**: SystemCapability.Web.Webview.Core
**Example**
```ts
// xxx.ets
import web_webview from '@ohos.web.webview'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
msgPort: web_webview.WebMessagePort[] = null;
build() {
Column() {
Button('close')
.onClick(() => {
if (this.msgPort && this.msgPort[1]) {
this.msgPort[1].close();
} else {
console.error("msgPort is null, Please initialize first");
}
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
```
### postMessageEvent
postMessageEvent(message: WebMessage): void
......@@ -214,6 +178,56 @@ struct WebComponent {
}
```
### close
close(): void
Closes this message port. To use this API, a message port must first be created using [createWebMessagePorts](#createwebmessageports).
**System capability**: SystemCapability.Web.Webview.Core
**Example**
```ts
// xxx.ets
import web_webview from '@ohos.web.webview'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
msgPort: web_webview.WebMessagePort[] = null;
build() {
Column() {
// Use createWebMessagePorts to create a message port.
Button('createWebMessagePorts')
.onClick(() => {
try {
this.msgPort = this.controller.createWebMessagePorts();
console.log("createWebMessagePorts size:" + this.msgPort.length)
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Button('close')
.onClick(() => {
try {
if (this.msgPort && this.msgPort.length == 2) {
this.msgPort[1].close();
} else {
console.error("msgPort is null, Please initialize first");
}
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
```
## WebviewController
Implements a **WebviewController** to control the behavior of the **\<Web>** component. A **WebviewController** can control only one **\<Web>** component, and the APIs (except static APIs) in the **WebviewController** can be invoked only after it has been bound to the target **\<Web>** component.
......@@ -228,7 +242,7 @@ Loads the dynamic link library (DLL) file of the web engine. This API can be cal
**Example**
The following code snippet exemplifies calling this API after the MainAbility is created.
The following code snippet exemplifies calling this API after the EntryAbility is created.
```ts
// xxx.ts
......@@ -239,36 +253,16 @@ export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
console.log("EntryAbility onCreate")
web_webview.WebviewController.initializeWebEngine()
globalThis.abilityWant = want
console.log("EntryAbility onCreate done")
}
}
```
### Creating an Object
```ts
// xxx.ets
import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
```
### setWebDebuggingAccess
static setWebDebuggingAccess(webDebuggingAccess: boolean): void
Sets whether to enable web debugging.
Sets whether to enable web debugging. For details, see [Debugging Frontend Pages by Using DevTools](../../web/web-debugging-with-devtools.md).
**System capability**: SystemCapability.Web.Webview.Core
......@@ -401,7 +395,7 @@ struct WebComponent {
.onClick(() => {
try {
// The URL to be loaded is of the Resource type.
this.controller.loadUrl($rawfile('xxx.html'));
this.controller.loadUrl($rawfile('index.html'));
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
......@@ -414,15 +408,16 @@ struct WebComponent {
2. Using a sandbox path. For details, see the example of loading local resource files in the sandbox in [Web](../arkui-ts/ts-basic-components-web.md#web).
```html
<!-- xxx.html -->
<!DOCTYPE html>
<html>
<body>
<p>Hello World</p>
</body>
</html>
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<p>Hello World</p>
</body>
</html>
```
### loadData
......@@ -1041,6 +1036,24 @@ struct Index {
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
Hello world!
</body>
<script type="text/javascript">
function htmlTest() {
str = objName.test("test function")
console.log('objName.test result:'+ str)
}
</script>
</html>
```
### runJavaScript
runJavaScript(script: string, callback : AsyncCallback\<string>): void
......@@ -1104,6 +1117,24 @@ struct WebComponent {
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
Hello world!
</body>
<script type="text/javascript">
function test() {
console.log('Ark WebComponent')
return "This value is from index.html"
}
</script>
</html>
```
### runJavaScript
runJavaScript(script: string): Promise\<string>
......@@ -1142,11 +1173,9 @@ import web_webview from '@ohos.web.webview'
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
@State webResult: string = '';
build() {
Column() {
Text(this.webResult).fontSize(20)
Web({ src: $rawfile('index.html'), controller: this.controller })
.javaScriptAccess(true)
.onPageEnd(e => {
......@@ -1168,6 +1197,24 @@ struct WebComponent {
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
Hello world!
</body>
<script type="text/javascript">
function test() {
console.log('Ark WebComponent')
return "This value is from index.html"
}
</script>
</html>
```
### deleteJavaScriptRegister
deleteJavaScriptRegister(name: string): void
......@@ -1644,14 +1691,15 @@ struct WebComponent {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: $rawfile('xxx.html'), controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -2439,14 +2487,15 @@ struct WebComponent {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -2511,14 +2560,15 @@ struct WebComponent {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -2583,14 +2633,15 @@ struct WebComponent {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -3106,7 +3157,7 @@ struct WebComponent {
.onClick(() => {
try {
let state = this.controller.serializeWebState();
// Obtain the value of globalThis.cacheDir from MainAbility.ts.
// globalThis.cacheDir is obtained from EntryAbility.ts.
let path = globalThis.cacheDir;
path += '/WebState';
// Synchronously open a file.
......@@ -3123,14 +3174,14 @@ struct WebComponent {
}
```
2. Modify **MainAbility.ts**.
2. Modify the **EntryAbility.ts** file.
Obtain the path of the application cache file.
```ts
// xxx.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import web_webview from '@ohos.web.webview';
export default class MainAbility extends UIAbility {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// Bind cacheDir to the globalThis object to implement data synchronization between the UIAbility component and the page.
globalThis.cacheDir = this.context.cacheDir;
......@@ -3178,7 +3229,7 @@ struct WebComponent {
Button('RestoreWebState')
.onClick(() => {
try {
// Obtain the value of globalThis.cacheDir from MainAbility.ts.
// globalThis.cacheDir is obtained from EntryAbility.ts.
let path = globalThis.cacheDir;
path += '/WebState';
// Synchronously open a file.
......@@ -3205,14 +3256,14 @@ struct WebComponent {
}
```
2. Modify **MainAbility.ts**.
2. Modify the **EntryAbility.ts** file.
Obtain the path of the application cache file.
```ts
// xxx.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import web_webview from '@ohos.web.webview';
export default class MainAbility extends UIAbility {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// Bind cacheDir to the globalThis object to implement data synchronization between the UIAbility component and the page.
globalThis.cacheDir = this.context.cacheDir;
......
......@@ -50,6 +50,7 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the
| syncLoad<sup>8+</sup> | boolean | Whether to load the image synchronously. By default, the image is loaded asynchronously. During synchronous loading, the UI thread is blocked and the placeholder diagram is not displayed.<br>Default value: **false**<br>Since API version 9, this API is supported in ArkTS widgets.|
| copyOption<sup>9+</sup> | [CopyOptions](ts-appendix-enums.md#copyoptions9) | Whether the image can be copied. (SVG images cannot be copied.)<br>When **copyOption** is set to a value other than **CopyOptions.None**, the image can be copied in various manners, such as long pressing, right-clicking, or pressing Ctrl+C.<br>Default value: **CopyOptions.None**<br>This API is supported in ArkTS widgets.|
| colorFilter<sup>9+</sup> | [ColorFilter](ts-types.md#colorfilter9) | Color filter of the image.<br>This API is supported in ArkTS widgets. |
| draggable<sup>9+</sup> | boolean | Whether the image is draggable. This attribute cannot be used together with the [onDragStart](ts-universal-events-drag-drop.md) event.<br>Default value: **false** |
> **NOTE**
>
......
......@@ -70,26 +70,26 @@ Web(options: { src: ResourceStr, controller: WebviewController | WebController})
Example of loading local resource files in the sandbox:
1. Use [globalthis](../../application-models/uiability-data-sync-with-ui.md#using-globalthis-between-uiability-and-page) to obtain the path of the sandbox.
```ts
// xxx.ets
import web_webview from '@ohos.web.webview'
let url = 'file://' + globalThis.filesDir + '/xxx.html'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
build() {
Column() {
// Load the files in the sandbox.
Web({ src: url, controller: this.controller })
}
}
}
```
```ts
// xxx.ets
import web_webview from '@ohos.web.webview'
let url = 'file://' + globalThis.filesDir + '/index.html'
@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController()
build() {
Column() {
// Load the files in the sandbox.
Web({ src: url, controller: this.controller })
}
}
}
```
2. Modify the **EntryAbility.ts** file.
2. Modify the **MainAbility.ts** file.
The following uses **filesDir** as an example to describe how to obtain the path of the sandbox. For details about how to obtain other paths, see [Obtaining the Application Development Path](../../application-models/application-context-stage.md#obtaining-the-application-development-path).
```ts
// xxx.ts
......@@ -105,6 +105,7 @@ Web(options: { src: ResourceStr, controller: WebviewController | WebController})
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
......@@ -569,15 +570,16 @@ Sets whether to display the horizontal scrollbar, including the default system s
controller: web_webview.WebviewController = new web_webview.WebviewController()
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
.horizontalScrollBarAccess(true)
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -622,15 +624,16 @@ Sets whether to display the vertical scrollbar, including the default system scr
controller: web_webview.WebviewController = new web_webview.WebviewController()
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
Web({ src: $rawfile('index.html'), controller: this.controller })
.verticalScrollBarAccess(true)
}
}
}
```
HTML file to be loaded:
```html
<!--xxx.html-->
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -651,6 +654,12 @@ Sets whether to display the vertical scrollbar, including the default system scr
</html>
```
### password
password(password: boolean)
Sets whether the password should be saved. This API is a void API.
### cacheMode
cacheMode(cacheMode: CacheMode)
......@@ -1217,6 +1226,18 @@ Sets whether to enable forcible dark mode for the web page. By default, this fea
}
```
### tableData
tableData(tableData: boolean)
Sets whether form data should be saved. This API is a void API.
### wideViewModeAccess
wideViewModeAccess(wideViewModeAccess: boolean)
Sets whether to support the viewport attribute of the HTML **\<meta>** tag. This API is a void API.
### pinchSmooth<sup>9+</sup>
pinchSmooth(isEnabled: boolean)
......@@ -1284,7 +1305,7 @@ Called when **alert()** is invoked to display an alert dialog box on the web pag
controller: web_webview.WebviewController = new web_webview.WebviewController()
build() {
Column() {
Web({ src: $rawfile("xxx.html"), controller: this.controller })
Web({ src: $rawfile("index.html"), controller: this.controller })
.onAlert((event) => {
console.log("event.url:" + event.url)
console.log("event.message:" + event.message)
......@@ -1314,8 +1335,9 @@ Called when **alert()** is invoked to display an alert dialog box on the web pag
}
```
```
<!--xxx.html-->
HTML file to be loaded:
```html
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -1366,7 +1388,7 @@ Called when this page is about to exit after the user refreshes or closes the pa
build() {
Column() {
Web({ src: $rawfile("xxx.html"), controller: this.controller })
Web({ src: $rawfile("index.html"), controller: this.controller })
.onBeforeUnload((event) => {
console.log("event.url:" + event.url)
console.log("event.message:" + event.message)
......@@ -1396,8 +1418,9 @@ Called when this page is about to exit after the user refreshes or closes the pa
}
```
```
<!--xxx.html-->
HTML file to be loaded:
```html
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -1448,7 +1471,7 @@ Called when **confirm()** is invoked by the web page.
build() {
Column() {
Web({ src: $rawfile("xxx.html"), controller: this.controller })
Web({ src: $rawfile("index.html"), controller: this.controller })
.onConfirm((event) => {
console.log("event.url:" + event.url)
console.log("event.message:" + event.message)
......@@ -1478,8 +1501,9 @@ Called when **confirm()** is invoked by the web page.
}
```
```
<!--xxx.html-->
HTML file to be loaded:
```html
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -1537,7 +1561,7 @@ onPrompt(callback: (event?: { url: string; message: string; value: string; resul
build() {
Column() {
Web({ src: $rawfile("xxx.html"), controller: this.controller })
Web({ src: $rawfile("index.html"), controller: this.controller })
.onPrompt((event) => {
console.log("url:" + event.url)
console.log("message:" + event.message)
......@@ -1568,8 +1592,9 @@ onPrompt(callback: (event?: { url: string; message: string; value: string; resul
}
```
```
<!--xxx.html-->
HTML file to be loaded:
```html
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
......@@ -1640,6 +1665,8 @@ Called to notify the host application of a JavaScript console message.
onDownloadStart(callback: (event?: { url: string, userAgent: string, contentDisposition: string, mimetype: string, contentLength: number }) => void)
Instructs the main application to start downloading a file.
**Parameters**
| Name | Type | Description |
......@@ -1948,6 +1975,26 @@ Called when loading of the web page is complete. This API is used by an applicat
}
```
### onSslErrorReceive<sup>(deprecated)</sup>
onSslErrorReceive(callback: (event?: { handler: Function, error: object }) => void)
Called when an SSL error occurs during resource loading.
> **NOTE**
>
> This API is supported since API version 8 and deprecated since API version 9. You are advised to use [onSslErrorEventReceive<sup>9+</sup>](#onsslerroreventreceive9) instead.
### onFileSelectorShow<sup>(deprecated)</sup>
onFileSelectorShow(callback: (event?: { callback: Function, fileSelector: object }) => void)
Called to process an HTML form whose input type is **file**, in response to the tapping of the **Select File** button.
> **NOTE**
>
> This API is supported since API version 8 and deprecated since API version 9. You are advised to use [onShowFileSelector<sup>9+</sup>](#onshowfileselector9) instead.
### onRenderExited<sup>9+</sup>
onRenderExited(callback: (event?: { renderExitReason: RenderExitReason }) => void)
......@@ -4560,6 +4607,7 @@ This API is deprecated since API version 9. You are advised to use [registerJava
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
......@@ -4620,7 +4668,7 @@ This API is deprecated since API version 9. You are advised to use [runJavaScrip
}
}
```
HTML file to be loaded:
```html
<!-- index.html -->
<!DOCTYPE html>
......@@ -4702,17 +4750,11 @@ This API is deprecated since API version 9. You are advised to use [clearHistory
Manages behavior of cookies in **\<Web>** components. All **\<Web>** components in an application share a **WebCookie**. You can use the **getCookieManager** API in **controller** to obtain the **WebCookie** for subsequent cookie management.
### setCookie<sup>(deprecated)</sup>
setCookie(url: string, value: string): boolean
setCookie(): boolean
Sets the cookie. This API returns the result synchronously. Returns **true** if the operation is successful; returns **false** otherwise.
This API is deprecated since API version 9. You are advised to use [setCookie<sup>9+</sup>](../apis/js-apis-webview.md#setcookie) instead.
**Parameters**
| Name | Type | Mandatory | Default Value | Description |
| ----- | ------ | ---- | ---- | ----------------- |
| url | string | Yes | - | URL of the cookie to set. A complete URL is recommended.|
| value | string | Yes | - | Value of the cookie to set. |
This API is deprecated since API version 9. You are advised to use [setCookie<sup>9+</sup>](../apis/js-apis-webview.md#setcookie) instead.
**Return value**
......@@ -4720,31 +4762,11 @@ This API is deprecated since API version 9. You are advised to use [setCookie<su
| ------- | ------------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
**Example**
```ts
// xxx.ets
@Entry
@Component
struct WebComponent {
controller: WebController = new WebController()
build() {
Column() {
Button('setCookie')
.onClick(() => {
let result = this.controller.getCookieManager().setCookie("https://www.example.com", "a=b")
console.log("result: " + result)
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
```
### saveCookie<sup>(deprecated)</sup>
saveCookie(): boolean
Saves the cookies in the memory to the drive. This API returns the result synchronously.
This API is deprecated since API version 9. You are advised to use [saveCookieAsync<sup>9+</sup>](../apis/js-apis-webview.md#savecookieasync) instead.
**Return value**
......@@ -4752,25 +4774,3 @@ This API is deprecated since API version 9. You are advised to use [saveCookieAs
| Type | Description |
| ------- | -------------------- |
| boolean | Operation result.|
**Example**
```ts
// xxx.ets
@Entry
@Component
struct WebComponent {
controller: WebController = new WebController()
build() {
Column() {
Button('saveCookie')
.onClick(() => {
let result = this.controller.getCookieManager().saveCookie()
console.log("result: " + result)
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
```
......@@ -28,8 +28,17 @@ To use DevTools for frontend page debugging, perform the following steps:
}
}
```
2. Declare the required permission in the **module.json5** file of the application project in DevEco Studio.
2. Connect your device to a PC, and configure port mapping on the PC as follows:
```
"requestPermissions":[
{
"name" : "ohos.permission.INTERNET"
}
]
```
3. Connect your device to a PC, and configure port mapping on the PC as follows:
```
// Configure port mapping.
......@@ -38,7 +47,7 @@ To use DevTools for frontend page debugging, perform the following steps:
hdc fport ls
```
3. Enter **chrome://inspect/\#devices** in the address box of the Chrome browser on the PC. Once the device is identified, you can get started with page debugging. The debugging effect is as follows:
4. Enter **chrome://inspect/\#devices** in the address box of the Chrome browser on the PC. Once the device is identified, you can get started with page debugging. The debugging effect is as follows:
**Figure 1** Page debugging effect
......
......@@ -2,13 +2,16 @@
- [Ability framework](changelogs-ability.md)
- [Account subsystem](changelogs-account_os_account.md)
- [ArkUI development framework](changelogs-arkui.md)
- [Multimedia subsystem - camera](changelogs-camera-sync.md)
- [Common library subsystem - container](changelogs-container.md)
- [Distributed data management subsystem](changelogs-distributeddatamgr.md)
- [Distributed data management](changelogs-distributeddatamgr.md)
- [File management subsystem](changelogs-filemanagement.md)
- [Input method framework](changelogs-inputmethod-framworks.md)
- [File management subsystem - MediaLibrary](changelogs-mediaLibrary.md)
- [Multimedia subsystem](changelogs-multimedia.md)
- [Communication subsystem - NFC](changelogs-nfc.md)
- [Common event and notification subsystem](changelogs-notification.md)
- Location subsystem
- [ohos.geoLocationManager](changelogs-ohos-geoLocationManager.md)
- [ohos.geoLocation](changelogs-ohos-geolocation.md)
......@@ -17,6 +20,7 @@
- [Resource scheduler subsystem](changelogs-resourceschedule.md)
- [Security subsystem](changelogs-security.md)
- [Telephony subsystem](changelogs-telephony.md)
- [Time service](changelogs-time.md)
- [Common library subsystem - URL](changelogs-url.md)
- [User IAM subsystem](changelogs-useriam.md)
- [Window manager subsystem](changelogs-window.md)
# ArkUI Subsystem ChangeLog
## cl.arkui.1 Restrictions on Data Type Declarations of State Variables
1. The data types of state variables decorated by state decorators must be explicitly declared. They cannot be declared as **any** or **Date**.
Example:
```ts
// xxx.ets
@Entry
@Component
struct DatePickerExample {
// Incorrect: @State isLunar: any = false
@State isLunar: boolean = false
// Incorrect: @State selectedDate: Date = new Date('2021-08-08')
private selectedDate: Date = new Date('2021-08-08')
build() {
Column() {
Button('Switch Calendar')
.margin({ top: 30 })
.onClick(() => {
this.isLunar = !this.isLunar
})
DatePicker({
start: new Date('1970-1-1'),
end: new Date('2100-1-1'),
selected: this.selectedDate
})
.lunar(this.isLunar)
.onChange((value: DatePickerResult) => {
this.selectedDate.setFullYear(value.year, value.month, value.day)
console.info('select current date is: ' + JSON.stringify(value))
})
}.width('100%')
}
}
```
![datePicker](../../../application-dev/reference/arkui-ts/figures/datePicker.gif)
2. The data type declaration of the **@State**, **@Provide**, **@Link**, or **@Consume** decorated state variables can consist of only one of the primitive data types or reference data types.
The **Length**, **ResourceStr**, and **ResourceColor** types are combinations of primitive data types or reference data types. Therefore, they cannot be used by the aforementioned types of state variables.
For details about the definitions of **Length**, **ResourceStr**, and **ResourceColor**, see [Types](../../../application-dev/reference/arkui-ts/ts-types.md).
Example:
```ts
// xxx.ets
@Entry
@Component
struct IndexPage {
// Incorrect: @State message: string | Resource = 'Hello World'
@State message: string = 'Hello World'
// Incorrect: @State message: ResourceStr = $r('app.string.hello')
@State resourceStr: Resource = $r('app.string.hello')
build() {
Row() {
Column() {
Text(`${this.message}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
```
![hello](../../../application-dev/quick-start/figures/hello.PNG)
**Change Impacts**
1. If the data type of a state variable decorated by a state decorator is declared as **any**, a build error will occur.
```ts
// ArkTS:ERROR Please define an explicit type, not any.
@State isLunar: any = false
```
2. If the data type of a state variable decorated by a state decorator is declared as **Date**, a build error will occur.
```ts
// ArkTS:ERROR The @State property 'selectedDate' cannot be a 'Date' object.
@State selectedDate: Date = new Date('2021-08-08')
```
3. If the data type of a **@State**, **@Provide**, **@Link**, and or **@Consume** decorated state variable is Length, **ResourceStr**, or **ResourceColor**, a build error will occur.
```ts
/* ArkTS:ERROR The state variable type here is 'ResourceStr', it contains both a simple type and an object type,
which are not allowed to be defined for state variable of a struct.*/
@State message: ResourceStr = $r('app.string.hello')
```
**Key API/Component Changes**
N/A
**Adaptation Guide**
1. Explicitly declare the data type for state variables decorated by state decorators.
2. If a state variable decorated by a state decorator uses the **Date** object, change it to a regular variable – a variable not decorated by any decorator.
3. Adapt the **@State**, **@Provide**, **@Link**, and **@Consume** decorated variables based on the following code snippet so that they do not use the **Length(string|number|Resource)**, **ResourceStr(string|Resource)**, and **ResourceColor(string|number|Color|Resource)** types:
```ts
// Incorrect:
@State message: ResourceStr = $r('app.string.hello')
// Corrected:
@State resourceStr: Resource = $r('app.string.hello')
```
## cl.arkui.2 Initialization Rules and Restrictions of Custom Components' Member Variables
Comply with the following rules when using constructors to initialize member variables:
| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **regular** | **@State** | **@Link** | **@Prop** | **@Provide** | **@Consume** | **@ObjectLink** |
|---------------------------------|----------------------------|------------|-----------|-----------|--------------|--------------|------------------|
| **regular** | Supported | Supported | Supported | Supported | Not supported | Not supported | Supported |
| **@State** | Supported | Supported | Supported | Supported | Supported | Supported | Supported |
| **@Link** | Not supported | Supported (1) | Supported (1) | Supported (1) | Supported (1) | Supported (1) | Supported (1) |
| **@Prop** | Supported | Supported | Supported | Supported | Supported | Supported | Supported |
| **@Provide** | Supported | Supported | Supported | Supported | Supported | Supported | Supported |
| **@Consume** | Not supported | Not supported | Not supported | Not supported | Not supported | Not supported | Not supported |
| **@ObjectLink** | Not supported | Not supported | Not supported | Not supported | Not supported | Not supported | Not supported |
| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **@StorageLink** | **@StorageProp** | **@LocalStorageLink** | **@LocalStorageProp** |
|------------------|------------------|------------------|-----------------------|------------------------|
| **regular** | Supported | Not supported | Not supported | Not supported |
| **@State** | Supported | Supported | Supported | Supported |
| **@Link** | Supported (1) | Supported (1) | Supported (1) | Supported (1) |
| **@Prop** | Supported | Supported | Supported | Supported |
| **@Provide** | Supported | Supported | Supported | Supported |
| **@Consume** | Not supported | Not supported | Not supported | Not supported |
| **@ObjectLink** | Not supported | Not supported | Not supported | Not supported |
> **NOTE**
>
> **Supported (1)**: The dollar sign ($) must be used, for example, **this.$varA**.
>
> **regular**: refers to a regular variable that is not decorated by any decorator.
**@StorageLink**, **@StorageProp**, **@LocalStorageLink**, and **@LocalStorageProp** variables cannot be initialized from the parent component.
**Change Impacts**
1. Variables decorated by **@LocalStorageLink** and **@LocalStorageProp** cannot be initialized from the parent component.
```ts
@Entry
@Component
struct LocalStorageComponent {
build() {
Column() {
Child({
/* ArkTS:ERROR Property 'simpleVarName' in the custom component 'Child' cannot
initialize here (forbidden to specify). */
simpleVarName: 1,
/* ArkTS:ERROR Property 'objectName' in the custom component 'Child' cannot
initialize here (forbidden to specify). */
objectName: new ClassA("x")
})
}
}
}
@Component
struct Child {
@LocalStorageLink("storageSimpleProp") simpleVarName: number = 0;
@LocalStorageProp("storageObjectProp") objectName: ClassA = new ClassA("x");
build() {}
}
```
2. The **@ObjectLink** decorated variable cannot be directly initialized from a decorated variable in the parent component. The source of the parent component must be an array item or object attribute decorated by **@State**, **@Link**, **@Provide**, **@Consume**, or **@ObjectLink**.
```ts
let NextID : number = 0;
@Observed class ClassA {
public id : number;
public c: number;
constructor(c: number) {
this.id = NextID++;
this.c = c;
}
}
@Component
struct Child {
@ObjectLink varA : ClassA;
build() {
Row() {
Text('ViewA-' + this.varA.id)
}
}
}
@Component
struct Parent {
@Link linkValue: ClassA
build() {
Column() {
/* ArkTS:ERROR The @Link property 'linkValue' cannot be assigned to
the @ObjectLink property 'varA'.*/
Child({ varA: this.linkValue })
}
}
}
```
**Key API/Component Changes**
N/A
**Adaptation Guide**
1. When building a child component, do not perform the build on the variables decorated by **@LocalStorageLink** and **@LocalStorageProp** in the child component.
To change these variables from the parent component, use the API provided by the **LocalStorage** (such as the **set** API) to assign values to them.
2. For details about how to use **@ObjectLink**, see [@ObjectLink](../../../application-dev/quick-start/arkts-observed-and-objectlink.md).
## cl.LocalStorage.1 Return Type Change of the get API
Changed the return type from **get\<T>(propName: string): T** to **get\<T>(propName: string): T | undefined**.
**Change Impact**
None
## cl.arkui.LocalStorage.2 Mandatory/Optional Change of the newValue Parameter in setOrCreate
**Change Impact**
API declaration before change:
```js
setOrCreate<T>(propName: string, newValue?: T): boolean
```
API declaration after change:
```js
setOrCreate<T>(propName: string, newValue: T): boolean
```
The **newValue** parameter becomes mandatory.
If it is not specified when an application calls the API, the build will fail after the SDK is replaced.
**Adaptation Guide**
```js
let storage = new LocalStorage();
storage.setOrCreate('propA', 'hello');
```
## cl.arkui.LocalStorage.3 link Parameter and Return Type Changes
**Change Impact**
API declaration before change:
```js
link<T>(propName: string, linkUser?: T, subscribersName?: string): T
```
API declaration after change:
```js
link<T>(propName: string): SubscribedAbstractProperty<T>
```
1. The second and third parameters of the **link** API are reserved for internal use by the framework. Therefore, the API is changed to contain only one parameter.
2. The return type **T** is changed to **SubscribedAbstractProperty**.
**Adaptation Guide**
```js
let storage = new LocalStorage({"PropA": "47"});
let linA = storage.link("PropA");
linA.set(50);
```
## cl.arkui.LocalStorage.4 setAndLink Parameter and Return Type Changes
**Change Impact**
API declaration before change:
```js
setAndLink<T>(propName: string, defaultValue: T, linkUser?: T, subscribersName?: string): T
```
API declaration after change:
```js
setAndLink<T>(propName: string, defaultValue: T): SubscribedAbstractProperty<T>
```
1. The third and fourth parameters of the **setAndLink** API are reserved for internal use by the framework. Therefore, the API is changed to contain two parameters.
2. The return type **T** is changed to **SubscribedAbstractProperty**.
**Adaptation Guide**
```js
let storage = new LocalStorage({"PropA": "47"});
let linA = storage.setAndLink("PropA", "48")
linA.set(50);
```
## cl.arkui.LocalStorage.5 prop Parameter and Return Type Changes
**Change Impact**
API declaration before change:
```js
prop<T>(propName: string, propUser?: T, subscribersName?: string): T
```
API declaration after change:
```js
prop<S>(propName: string): SubscribedAbstractProperty<S>
```
1. The second and third parameters of the **prop** API are reserved for internal use by the framework. Therefore, the API is changed to contain only one parameter.
2. The return type **T** is changed to **SubscribedAbstractProperty**.
**Adaptation Guide**
```js
let storage = new LocalStorage({"PropA": "47"});
let propA = storage.prop("PropA");
propA.set(51); // one-way sync
```
## cl.arkui.LocalStorage.6 setAndProp Parameter and Return Type Changes
**Change Impact**
API declaration before change:
```js
setAndProp<T>(propName: string, defaultValue: T, propUser?: T, subscribersName?: string): T
```
API declaration after change:
```js
setAndProp<S>(propName: string, defaultValue: S): SubscribedAbstractProperty<S>
```
1. The third and fourth parameters of the **setAndProp** API are reserved for internal use by the framework. Therefore, the API is changed to contain two parameters.
2. The return type **T** is changed to **SubscribedAbstractProperty**.
**Adaptation Guide**
```js
let storage = new LocalStorage({"PropA": "47"});
let propA = storage.setAndProp("PropA", "48");
propA.set(51); // one-way sync
```
\ No newline at end of file
# Input Method Framework ChangeLog
## cl.inputmethod_frameworks.1 API Filename Change
The following modules do not comply with the OpenHarmony API file naming rules. Therefore, they are modified in API version 9 and later.
**Change Impacts**
The SDK after the change is incompatible with the earlier versions. Therefore, adaptation is required for applications developed in earlier versions so that they can be properly built with the SDK in the new version.
**Key API/Component Changes**
| Module| File Name Before Change| File Name After Change|
|------|--------------|--------------|
| Input method framework module| @ohos.inputmethod.d.ts |@ohos.inputMethod.d.ts |
| Input method service module|@ohos.inputmethodengine.d.ts | @ohos.inputMethodEngine.d.ts |
| Input method ExtentionAbility module| @ohos.inputmethodextensionability.d.ts | @ohos.InputMethodExtensionAbility.d.ts |
| Input method ExtentionContext module|@ohos.inputmethodextensioncontext.d.ts | @ohos.InputMethodExtensionContext.d.ts |
| Input method subtype module| @ohos.inputMethodSubtype.d.ts | @ohos.InputMethodSubtype.d.ts |
**Adaptation Guide**
In the application code, change the name of the d.ts file following **import** to the new file name, which complies with the UpperCamelCase or lowerCamelCase style.
Example:
```js
import inputMethodEngine from '@ohos.inputMethodEngine';
```
# Common Event and Notification Subsystem ChangeLog
## cl.notification.1 Deleting Deprecated APIs (Version 9)
In the event notification exception handling rectification, some APIs in API version 9 are marked as deprecated, and these APIs need to be deleted, according to OpenHarmony API specifications.
**Change Impacts**
The application developed based on earlier versions needs to use new APIs to replace the deleted ones. Otherwise, the application compilation will be affected.
**Key API/Component Changes**
Deprecated APIs in API version 9 will be deleted, and they will be replaced with new ones with same names.
| Original API | New API |
| ----------------------- | -------------------------------- |
| @ohos.commonEvent.d.ts | @ohos.commonEventManager.d.ts |
| @ohos.notification.d.ts | @ohos.notificationManager.d.ts |
| @ohos.notification.d.ts | @ohos.notificationSubscribe.d.ts |
APIs or attributes are deleted:
- @ohos.notification.d.ts
- The **publishAsBundle**, **cancelAsBundle**, **isNotificationSlotEnabled**, **setSyncNotificationEnabledWithoutApp**, and **getSyncNotificationEnabledWithoutApp** APIs are deleted. Replace them with APIs with same names in **api/@ohos.notificationManager.d.ts**.
- The **enableNotificationSlot** API is deleted. Replace it with **setNotificationEnableSlot** in **api/@ohos.notificationManager.d.ts**.
- The export classes **NotificationActionButton**, **NotificationBasicContent**, **NotificationContent**, **NotificationLongTextContent**, **NotificationMultiLineContent**, **NotificationPictureContent**, **NotificationFlags**, **NotificationFlagStatus**, **NotificationRequest**, **DistributedOptions**, **NotificationSlot**, **NotificationSorting**, **NotificationTemplate**, and **NotificationUserInput** are deleted. Replace them with the export classes with the same names in **api/@ohos.notificationManager.d.ts**.
- The export classes **NotificationSubscribeInfo**, **NotificationSubscriber**, **SubscribeCallbackData**, and **EnabledNotificationCallbackData** are deleted. Replace them with the export classes with the same names in **api/@ohos.notificationSubscribe.d.ts**.
**Adaptation Guide**
The original APIs are only migrated to the new namespace. Therefore, you can modify **import** to solve the adaptation problem.
If the original API uses **@ohos.commonEvent**:
```js
import commonEvent from '@ohos.commonEvent';
```
You can directly modify **import** to switch to the new namespace:
```js
import commonEvent from '@ohos.commonEventManager';
```
**@ohos.notification** is split into two namespaces. You need to select a new namespace for adaptation.
In addition, exception handling is needed. For details, see the API reference for the new APIs.
# Time Subsystem ChangeLog
## cl.time.1 API Error Change
Errors thrown by timer APIs of the time subsystem: **202** (non-system application) and **401** (invalid parameters).
**Change Impacts**
The API change is forward compatible. Applications developed based on earlier versions can still use the APIs, and corresponding error handling is added. The original functions are not affected.
**Key API/Component Changes**
Before change:
- The API throws an error message without an error code.
After change:
- The API throws an error message with an error code. Error code **202** indicates that the application is not a system application, and error code **401** indicates that the parameters are invalid.
| Module | Class | Method/Attribute/Enumeration/Constant | Change Type|
| ----------------- | ----------- | ------------------------------------------------------------ | -------- |
| @ohos.systemTimer | systemTimer | function createTimer(options: TimerOptions, callback: AsyncCallback\<number>): void | Changed |
| @ohos.systemTimer | systemTimer | function createTimer(options: TimerOptions): Promise\<number> | Changed |
| @ohos.systemTimer | systemTimer | function startTimer(timer: number, triggerTime: number, callback: AsyncCallback\<void>): void | Changed |
| @ohos.systemTimer | systemTimer | function startTimer(timer: number, triggerTime: number): Promise\<void> | Changed |
| @ohos.systemTimer | systemTimer | function stopTimer(timer: number, callback: AsyncCallback\<void>): void | Changed |
| @ohos.systemTimer | systemTimer | function stopTimer(timer: number): Promise\<void> | Changed |
| @ohos.systemTimer | systemTimer | function destroyTimer(timer: number, callback: AsyncCallback\<void>): void | Changed |
| @ohos.systemTimer | systemTimer | function destroyTimer(timer: number): Promise\<void> | Changed |
**Adaptation Guide**
Refer to the code below to capture errors when **systemTimer** APIs are called in applications.
createTimer callback mode:
**Example**
```js
export default {
systemTimer () {
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat: false
};
try {
systemTimer.createTimer(options, (error, timerId) => {
if (error) {
// Capture the permission denial error.
console.info(`Failed to create timer. message: ${error.message}, code: ${error.code}`);
}
console.info(`Succeeded in creating timer. timerId: ${timerId}`);
});
} catch(e) {
// Capture the parameter verification error.
console.info(`Failed to create timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
createTimer promise mode:
**Example**
```js
export default {
systemTimer () {
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat: false
};
try {
systemTimer.createTimer(options).then((timerId) => {
console.info(`Succeeded in creating timer. timerId: ${timerId}`);
}).catch((error) => {
// Capture the permission denial error.
console.info(`Failed to create timer. message: ${error.message}, code: ${error.code}`);
});
} catch(e) {
// Capture the parameter verification error.
console.info(`Failed to create timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
startTimer callback mode:
**Example**
```js
export default {
async systemTimer () {
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
try {
systemTimer.startTimer(timerId, triggerTime, (error) => {
if (error) {
// Capture the permission denial error.
console.error(`Failed to start timer. message: ${error.message}, code: ${error.code}`);
}
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to start timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
startTimer promise mode:
**Example**
```js
export default {
async systemTimer (){
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
try {
systemTimer.startTimer(timerId, triggerTime).then((data) => {
console.log(`Succeeded in startting timer. Data:` + data);
}).catch((error) => {
// Capture the permission denial error.
console.info(`Failed to start timer. message: ${error.message}, code: ${error.code}`);
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to start timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
stopTimer callback mode:
**Example**
```js
export default {
async systemTimer () {
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
systemTimer.startTimer(timerId, triggerTime);
try {
systemTimer.stopTimer(timerId, triggerTime, (error) => {
if (error) {
// Capture the permission denial error.
console.error(`Failed to stop timer. message: ${error.message}, code: ${error.code}`);
}
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to stop timer. message: ${e.message}, code: ${e.code}`);
}
}
}git
```
stopTimer promise mode:
**Example**
```js
export default {
async systemTimer (){
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
systemTimer.startTimer(timerId, triggerTime);
try {
systemTimer.stopTimer(timerId, triggerTime).then((data) => {
console.log(`Succeeded in stop timer. Data:` + data);
}).catch((error) => {
// Capture the permission denial error.
console.info(`Failed to stop timer. message: ${error.message}, code: ${error.code}`);
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to stop timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
destroyTimer callback mode:
**Example**
```js
export default {
async systemTimer () {
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
systemTimer.startTimer(timerId, triggerTime);
systemTimer.stopTimer(timerId);
try {
systemTimer.destroyTimer(timerId, triggerTime, (error) => {
if (error) {
// Capture the permission denial error.
console.error(`Failed to destroy timer. message: ${error.message}, code: ${error.code}`);
}
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to destroy timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
destroyTimer promise mode:
**Example**
```js
export default {
async systemTimer (){
let options = {
type: systemTimer.TIMER_TYPE_REALTIME,
repeat:false
}
let timerId = await systemTimer.createTimer(options);
let triggerTime = new Date().getTime();
triggerTime += 3000;
systemTimer.startTimer(timerId, triggerTime);
systemTimer.stopTimer(timerId);
try {
systemTimer.destroyTimer(timerId, triggerTime).then((data) => {
console.log(`Succeeded in destroy timer. Data:` + data);
}).catch((error) => {
// Capture the permission denial error.
console.info(`Failed to destroy timer. message: ${error.message}, code: ${error.code}`);
});
} catch (e) {
// Capture the parameter verification error.
console.info(`Failed to destroy timer. message: ${e.message}, code: ${e.code}`);
}
}
}
```
## cl.time.2 API Error Change
Errors thrown by timer APIs of the time subsystem: **201** (permission denied), **202** (non-system application), and **401** (invalid parameters).
**Change Impacts**
Applications developed based on earlier versions can still use the APIs. When new APIs are used, errors must be captured and processed.
**Key API/Component Changes**
Before change:
- The API throws an error message with error code **-1**.
After change:
- The API throws an error message with an error code. Error code **201** indicates that the permission is denied, error code **202** indicates that the application is not a system application, and error code **401** indicates that the parameters are invalid.
Deprecated APIs can be replaced with new ones with same names.
| Original API | New API |
| ---------------- | -------------------- |
| @ohos.systemTime | @ohos.systemDateTime |
**Adaptation Guide**
Refer to the code below to capture errors when **systemTime** APIs are called in applications. In the examples, the **setTime** API is invoked.
In callback mode:
**Example**
```js
import systemDateTime from @ohos.systemDateTime
// Set the system time to 2021-01-20 02:36:25.
let time = 1611081385000;
try {
systemDateTime.setTime(time, (error) => {
// Capture permission denial and non-system-application errors.
if (error) {
console.info(`Failed to setting time. message: ${error.message}, code: ${error.code}`);
return;
}
console.info(`Succeeded in setting time.`);
})
} catch(e) {
// Capture the parameter verification error.
console.info(`Failed to set time. message: ${e.message}, code: ${e.code}`);
}
```
In promise mode:
**Example**
```js
import systemDateTime from @ohos.systemDateTime
// Set the system time to 2021-01-20 02:36:25.
let time = 1611081385000;
try {
systemDateTime.setTime(time).then(() => {
console.info(`Succeeded in setting time.`);
}).catch((error) => {
// Capture permission denial and non-system-application errors.
console.info(`Failed to setting time. message: ${error.message}, code: ${error.code}`);
});
} catch(e) {
// Capture the parameter verification error.
console.info(`Failed to set time. message: ${e.message}, code: ${e.code}`);
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册