# 针对API 12应用的变更

## Ability Kit

### restartApp接口变更

**变更原因**

避免恶意应用在非获焦状态下重启自身，实现霸屏。

**变更影响**

此变更涉及应用适配。开发者需要在应用处于获焦状态时使用该接口，否则会影响功能。

**该能力起始支持的API Level**

12

**适配指导**

开发者需要在应用处于获焦状态时调用restartApp接口。

**示例：**

```ts
import { UIAbility, Want } from '@kit.AbilityKit';

export default class MyAbility extends UIAbility {
  onForeground() {
    let applicationContext = this.context.getApplicationContext();
    let want: Want = {
      bundleName: 'com.example.myapp',
      abilityName: 'EntryAbility'
    };
    try {
      applicationContext.restartApp(want);
    } catch (error) {
      console.error(`restartApp fail, error: ${JSON.stringify(error)}`);
    }
  }
}
```

## ArkData

### ValueType增加类型

**变更原因**

由于接口能力增强，ValueType需要增加类型。

**变更影响**

此变更涉及应用适配，ValueType增加类型，会导致getValue的返回值类型增加。当高低版本设备互通时，当高版本设备设置的数据类型为本次新增的类型时，由于低版本设备不支持新增的类型，会导致低版本设备上getValue失败。

**该能力起始支持的API Level**

12

**变更的接口/组件**

变更之前，ValueType类型如下：

```ts
type ValueType = number | string | image.PixelMap | Want | ArrayBuffer
```

变更之后，ValueType类型如下：

```ts
type ValueType = number | string  | boolean | image.PixelMap | Want | ArrayBuffer | object | null | undefined
```

**适配指导**

getValue接口的使用可参考[getValue示例代码](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-data-unifieddatachannel-V5#getvalue12)。

## ArkTS

### Sendable容器TypedArray提供的map方法的回调函数声明变更

**变更原因**

Sendable容器TypedArray提供map方法。该方法对TypedArray中的每个元素进行某种操作或转换（通过callbackFn的返回值），并返回一个新的TypedArray，其中包含经过映射函数处理后的结果。

以Uint8Array为例，变更前，map函数的callbackFn声明无返回值，导致转换后的数据丢失，引起开发者使用上的困惑。

* map方法的回调函数声明为map(callbackFn: TypedArrayForEachCallback<number, Uint8Array>): Uint8Array;
* 而TypedArrayForEachCallback 的定义为无返回值的：type TypedArrayForEachCallback<ElementType, ArrayType> = (value: ElementType, index: number, array: ArrayType) => void;

**变更影响**

此变更涉及应用适配。

**变更前**

* 情况一： map函数中的callbackFn无返回值，能通过编译，但是无法实现map功能
* 情况二： map函数中的callbackFn有返回值，但是返回类型不是number，能通过编译，能实现map功能
* 情况三： map函数中的callbackFn有返回值，且返回类型是number，能通过编译，能实现map功能

```ts
let arr = [1, 2, 3, 4, 5];

// 创建一个Uint8Array
let uint8: collections.Uint8Array = new collections.Uint8Array(arr);

// 情况一：不能完成map功能：callbackFn无返回值，map函数返回新的collections.Uint8Array
let zeroMappedArray: collections.Uint8Array = uint8.map((value: number) => {}); // 能通过编译
console.info('' + zeroMappedArray); // 输出: collections.Uint8Array [0, 0, 0, 0, 0]

// 情况二：能完成map功能：callbackFn返回map后的元素值，但类型为string，map函数返回新的collections.Uint8Array
let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => value + "1"); // 能通过编译
console.info('' + wrongTypeMapped); // 输出: collections.Uint8Array [11, 21, 31, 41, 51]

// 情况三：能完成map功能：callbackFn返回map后的元素值，map函数返回新的collections.Uint8Array
let normalMapped: collections.Uint8Array = uint8.map((value: number) => value * 2); // 能通过编译
console.info('' + normalMapped); // 输出: collections.Uint8Array [2, 4, 6, 8, 10]
```

**变更后**

* 情况一： map函数中的callbackFn无返回值，不能通过编译
* 情况二： map函数中的callbackFn有返回值，但是返回类型不是number，不能通过编译
* 情况三： map函数中的callbackFn有返回值，且返回类型是number，能通过编译，能实现map功能

```ts
let arr = [1, 2, 3, 4, 5];

// 创建一个Uint8Array
let uint8: collections.Uint8Array = new collections.Uint8Array(arr);

// 情况一：不能完成map功能：callbackFn无返回值，map函数返回新的collections.Uint8Array
let zeroMappedArray: collections.Uint8Array = uint8.map((value: number) => {}); // 不能通过编译

// 情况二：能完成map功能：callbackFn返回map后的元素值，但类型为string，map函数返回新的collections.Uint8Array
let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => value + "1"); // 不能通过编译

// 情况三：能完成map功能：callbackFn返回map后的元素值，map函数返回新的collections.Uint8Array
let normalMapped: collections.Uint8Array = uint8.map((value: number) => value * 2); // 能通过编译
console.info('' + normalMapped); // 输出: collections.Uint8Array [2, 4, 6, 8, 10]
```

**该能力起始支持的API Level**

API12

**变更的接口/组件**

/interface/sdk-js/arkts/@arkts.collections.d.ets中TypedArray（包括Int8Array/Uint8Array/Int16Array/Uint16Array/Int32Array/Uint32Array）的map接口

**适配指导**

* 举例：上述场景二的例子，可以做如下修改：

  ```ts
  let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => parseInt(value + "1")); // 通过parseInt进行字符串到number的转换
  ```

* 详细说明参见：接口使用的示例代码:

  [ArkTS容器集 - TypedArray](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-arkts-collections-V5#collectionstypedarray)

### Sendable语法规则编译检查完善

**变更原因**

Sendable对象需要遵循一定[使用规则](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/sendable-constraints)，在Sendable泛型类的部分语法中，编译器没有对应的检查，导致这些语法下的Sendable对象用在并发场景中运行异常但是没有无编译时错误。在本次版本更新中，我们修复了这些场景下Sendable约束的编译时检查，将运行时异常提前到编译时。旨在通过编译时错误，帮助开发者更早发现Sendable使用约束，减少运行时定位成本。

**变更影响**

此变更涉及应用适配。

变更前：当Sendable泛型类用作类型标注时，类型形参可以使用Non-sendable类型，DevEco编辑界面没有错误提示，编译没有报错。

变更后：当Sendable泛型类用作类型标注时，类型形参不可以使用Non-sendable类型，DevEco编辑界面有错误提示，编译有报错。

对于使用Sendable泛型类进行声明，但是被赋值为Non-sendable对象的变量/参数/返回值，如果它们被用在并发实例共享的场景中，变更前会有运行时异常，变更后错误提前至编译期。如果它们被当作普通对象使用时，变更前运行时不报错，变更后编译器新增报错。

具体场景示例：

Sendable泛型类约束

场景一：当Sendable对象被用在多线程共享时，影响：运行时异常提前到编译时

变更前

```ts
// declaration.ets
export class NonSendableClass {};

// main.ets
import { NonSendableClass } from './declaration';
import collections from '@arkts.collections';

@Sendable
class SendableClass {
    private arr: collections.Array<NonSendableClass> = new collections.Array();
    constructor() {
        this.arr.push(new NonSendableClass()); // Runtime ERROR
    }
}
let sendableclassObject: SendableClass = new SendableClass();
```

变更后

```ts
// declaration.ets
export class NonSendableClass {};

// main.ets
import { NonSendableClass } from './declaration';
import collections from '@arkts.collections';

@Sendable
class SendableClass {
    private arr: collections.Array<NonSendableClass> = new collections.Array(); // ArkTS compile-time error
    constructor() {
        this.arr.push(new NonSendableClass());
    }
}
let sendableclassObject: SendableClass = new SendableClass();
```

场景二：Sendable对象被当作普通对象使用时，影响：产生新增编译报错

变更前

```ts
@Sendable
class SendableClassA<T> {
    one: string = '1';
}
class NoneSendableClassA<T> {
    one: string = '1';
}
let sendableObjectA: SendableClassA<NoneSendableClassA<number>> = new SendableClassA();
```

变更后

```ts
@Sendable
class SendableClassA<T> {
    one: string = '1';
}
class NoneSendableClassA<T> {
    one: string = '1';
}
let sendableObjectA: SendableClassA<NoneSendableClassA<number>> = new SendableClassA(); // ArkTS compile-time error
```

**该能力起始支持的API Level**

ArkTS Sendable语法检查从API 12起启用。

**变更的接口/组件**

不涉及。

**适配指导**

Sendable泛型类的类型必须使用Sendable类型。

### Sendable赋值语法规则编译检查完善

**访问级别**

其他

**变更原因**

Sendable赋值时需要遵循一定[使用规则](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/sendable-constraints)，但是在Non-sendable对象赋值给Sendable类型的部分场景中，编译没有对应的检查，导致这些场景下的Non-sendable对象被当成Sendable对象使用，运行异常但是没有编译时报错。在本次版本更新中，我们修复了这些场景下Sendable赋值约束的编译时检查，将运行时异常提前到编译时。旨在通过编译时错误，帮助开发者更早发现Sendable使用约束，减少运行时定位成本。

错误对象：使用Sendable类型/接口进行声明，但是被赋值为Non-sendable对象的变量/参数/返回值。

**变更影响**

此变更涉及应用适配。

变更前：Non-sendable对象赋值给Sendable类型的部分场景中，DevEco编辑界面没有错误提示，编译没有报错。

变更后：Non-sendable对象赋值给Sendable类型的部分场景中，DevEco编辑界面有错误提示，编译有报错。

当错误对象被当成Sendable对象使用时，将运行时报错提前到编译期。当错误对象被当做普通对象使用时，运行时不报错但编译期新增报错。变更前，在一些场景下Non-sendable对象可以被赋值给Sendable类型。变更后，Non-sendable对象不可以赋值给Sendable类型。

下面的场景将会报错：

Sendable赋值约束

场景一：当错误对象被当成Sendable对象使用时

变更前

```ts
// declaration.ets
export class NonSendableClass {};
@Sendable
export class SendableClass {};

export class NonSendableClassT<T> {};
@Sendable
export class SendableClassT<T> {};

// main.ets
import { NonSendableClass, SendableClass, NonSendableClassT, SendableClassT } from './declaration';
import collections from '@arkts.collections';

@Sendable
class SendableData {
    propA: SendableClass = new NonSendableClass(); // Runtime ERROR
    propB: SendableClassT<number>;
    propC: SendableClass;
    propD: SendableClass;
    propE: SendableClass;

    constructor(sendableT: SendableClassT<number>) {
      const sendableList: SendableClass[] = [new NonSendableClass()];
      this.propB = new NonSendableClassT<number>(); // Runtime ERROR
      this.propC = this.getSendable(); // Runtime ERROR
      this.propD = sendableList[0]; // Runtime ERROR
      this.propE = sendableT; // Runtime ERROR
    }

    getSendable(): SendableClass {
        return new NonSendableClass();
    }
}

new SendableData(new NonSendableClassT<number>());

const sendable: SendableClassT<number> = new NonSendableClassT<number>();
const sendableArray: collections.Array<SendableClass> = new collections.Array<SendableClass>();
sendableArray.push(sendable); // Runtime ERROR
```

变更后

```ts
// declaration.ets
export class NonSendableClass {};
@Sendable
export class SendableClass {};

export class NonSendableClassT<T> {};
@Sendable
export class SendableClassT<T> {};

// main.ets
import { NonSendableClass, SendableClass, NonSendableClassT, SendableClassT } from './declaration';
import collections from '@arkts.collections';

@Sendable
class SendableData {
    propA: SendableClass = new NonSendableClass(); // ArkTS compile-time error
    propB: SendableClassT<number>;
    propC: SendableClass;
    propD: SendableClass;
    propE: SendableClass;
    
    constructor(sendableT: SendableClassT<number>) {
      const sendableList: SendableClass[] = [new NonSendableClass()]; // ArkTS compile-time error
      this.propB = new NonSendableClassT<number>(); // ArkTS compile-time error
      this.propC = this.getSendable(); 
      this.propD = sendableList[0]; 
      this.propE = sendableT;
    }

    getSendable(): SendableClass {
        return new NonSendableClass(); // ArkTS compile-time error
    }
}

new SendableData(new NonSendableClassT<number>()); // ArkTS compile-time error

const sendable: SendableClassT<number> = new NonSendableClassT<number>(); // ArkTS compile-time error
const sendableArray: collections.Array<SendableClass> = new collections.Array<SendableClass>();
sendableArray.push(sendable);
```

场景二：错误对象被当作普通对象使用时，影响：新增报错

变更前

```ts
class NonSendableClass {};
@Sendable
class SendableClass {};

class NonSendableClassT<T> {};
@Sendable
class SendableClassT<T> {};

function getSendable(): SendableClass {
    return new NonSendableClass();
}

const objectA: SendableClass = getSendable();
const objectB: SendableClassT<number> = new NonSendableClassT<number>();
```

变更后

```ts
class NonSendableClass {};
@Sendable
class SendableClass {};

class NonSendableClassT<T> {};
@Sendable
class SendableClassT<T> {};

function getSendable(): SendableClass {
    return new NonSendableClass(); // ArkTS compile-time error
}

const objectA: SendableClass = getSendable();
const objectB: SendableClassT<number> = new NonSendableClassT<number>(); // ArkTS compile-time error
```

**该能力起始支持的API Level**

ArkTS Sendable语法检查从API 12起启用。

**变更的接口/组件**

不涉及。

**适配指导**

避免把Non-sendable对象赋值给Sendable变量/参数/返回值。

## ArkUI

### 按下鼠标任意按键移动鼠标情况下不再上报鼠标事件的行为变更

**变更原因**

优化鼠标按压态下拖移的执行效率。

**变更影响**

此变更涉及应用适配。

变更前：按压鼠标按键拖移过程中，中途经过的控件会收到鼠标事件。

变更后：按压鼠标按键拖移过程中，中途经过的控件不再会收到鼠标事件。

|变更前(按住鼠标进行拖移)|变更后(按住鼠标进行拖移)|
|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a8/v3/aKW6vbPkSWmTpXa5Ow1K2A/zh-cn_image_0000001956262518.gif?HW-CC-KV=V1&HW-CC-Date=20261008T180234Z&HW-CC-Expire=31536000000&HW-CC-Sign=7CC8D1BF3E430D86B6C953F12832DBD52B2636C156004109217CAFEFF94AC1B3)|![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a4/v3/sQr5YK9YQO-I0r_87ghNAg/zh-cn_image_0000001993301641.gif?HW-CC-KV=V1&HW-CC-Date=20261008T180234Z&HW-CC-Expire=31536000000&HW-CC-Sign=A986DD27ED46CC5DF5037238A06FD30F189ADFD413A96FFD0DA428A9563E37ED)|

**该能力起始支持的API Level**

12

**变更的接口/组件**

[onHover](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-events-hover#onhover)

[onMouse](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-mouse-key-V5#onmouse)

**适配指导**

如果开发者需要在按住鼠标按键移动情况下，中间经过的控件也要有hover效果，则需要整改为通过点击开始时命中的控件接收鼠标事件，自行处理。如果当前鼠标移动为拖拽场景，则不要使用[onHover](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-events-hover#onhover)和[onMouse](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-mouse-key-V5#onmouse)而是通过[onDragMove](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-events-drag-drop-V5#ondragmove)去处理鼠标移动事件。

## 构造@ComponentV2修饰的自定义组件时，增加对常规变量的构造赋值校验

**变更原因**

在@ComponentV2修饰的自定义组件中使用@Local、@Provider()、@Consumer()、常规变量(没有任何装饰器修饰的，不涉及更新的普通变量)，在构造的时候传参赋值，进行校验并输出错误信息。

**变更影响**

此变更涉及应用适配。

执行下列用例：

```ts
@Entry
@ComponentV2
struct v2DecoratorInitFromParent {
  build() {
    Column() {
      testChild({
        regular_value: "hello",
        local_value: "hello",
        provider_value: "hello",
        consumer_value: "hello"
      })
    }
  }
}

@ComponentV2
struct testChild {
  regular_value: string = "hello";
  @Local local_value: string = "hello";
  @Provider() provider_value: string = "hello";
  @Consumer() consumer_value: string = "hello";
  build() {}
}
```

变更前无报错

变更后报错信息为：

Property 'regular_value' in the custom component 'testChild' cannot initialize here (forbidden to specify).

Property 'local_value' in the custom component 'testChild' cannot initialize here (forbidden to specify).

Property 'provider_value' in the custom component 'testChild' cannot initialize here (forbidden to specify).

Property 'consumer_value' in the custom component 'testChild' cannot initialize here (forbidden to specify).

**该能力起始支持的API Level**

V2装饰器从API 12开始提供。

**适配指导**

如果开发者不按规范使用对应范式，则需按日志提示信息进行修改。

### @ohos.arkui.advanced.SubHeader删除SymbolRenderingStrategy和SymbolEffectStrategy

**变更原因**

SymbolGlyph中已定义SymbolRenderingStrategy和SymbolEffectStrategy，避免重复枚举定义。减少开发者引用工作量。

**变更影响**

此变更涉及应用适配。

变更前，引用@ohos.arkui.advanced.SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy，运行时报错：

1.Error message:the requested module '@ohos.arkui.advanced.SubHeader' does not provide an export name 'SymbolRenderingStrategy' and 'SymbolEffectStrategy'.

变更后，引用@ohos.arkui.advanced.SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy，编译期报错：

1.Module '@ohos.arkui.advanced.SubHeader' has no exported member 'SymbolRenderingStrategy' and 'SymbolEffectStrategy'.

**该能力起始支持的API Level**

12

**适配指导**

如果开发者不按规范使用对应范式，则需按编译提示信息进行修改。参考API文档，删除引用SubHeader中SymbolRenderingStrategy和SymbolEffectStrategy，自动引用SymbolGlyph中SymbolRenderingStrategy和SymbolEffectStrategy。

适配示例：

```ts
import { promptAction, OperationType, SubHeader } from '@kit.ArkUI'

@Entry
@Component
struct SubHeaderExample {
  build() {
    Column() {
      SubHeader({
        icon: $r('sys.symbol.ohos_wifi'),
        iconSymbolOptions: {
          effectStrategy: SymbolEffectStrategy.HIERARCHICAL,
          renderingStrategy: SymbolRenderingStrategy.MULTIPLE_COLOR,
          fontColor: [Color.Blue, Color.Grey, Color.Green],
        },
        secondaryTitle: '标题',
        operationType: OperationType.BUTTON,
        operationItem: [{ value: '操作',
          action: () => {
            promptAction.showToast({ message: 'demo' })
          }
        }]
      })
    }
  }
}
```

### setWindowSystemBarEnable、setSystemBarEnable不在PC/2in1设备生效

**变更原因**

在PC/2in1设备下，全屏状态下的状态栏显示控制由系统布局约束，无需再调用接口去控制状态栏的显示和隐藏。即设置的setWindowSystemBarEnable、setSystemBarEnable在PC/2in1设备上不生效。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/71/v3/EPZWTCwKTsuWOC95Uudxvw/zh-cn_image_0000001993261849.png?HW-CC-KV=V1&HW-CC-Date=20261008T180234Z&HW-CC-Expire=31536000000&HW-CC-Sign=AB22365EC5095161D470084EA1247B307B4C253AC557EC049B7773ED9A3502EC)

**变更影响**

此变更涉及应用适配。

此变更从API 12起生效，使用API 11及之前版本SDK进行编译的应用不受影响。

变更前PC/2in1设备上全屏调用此接口可以显示和隐藏状态栏。

变更后PC/2in1设备上窗口布局会自动适配避让逻辑，无需调用接口控制。

**该能力起始支持的API Level**

9

**变更的接口/组件**

@ohos.window.d.ts

setWindowSystemBarEnable

setSystemBarEnable

**适配指导**

默认效果变更，无需适配，但应注意变更后的默认效果是否影响应用显示效果。

## User Authentication Kit

### @ohos.useriam.userAuthIcon导出命名变更

**变更原因**

不符合命名规范，需将导出命名从小驼峰userAuthIcon改为大驼峰UserAuthIcon。

**变更影响**

此变更涉及应用适配。

变更前

```ts
import { userAuth, userAuthIcon } from '@kit.UserAuthenticationKit';
```

变更后

```ts
import { userAuth, UserAuthIcon } from '@kit.UserAuthenticationKit';
```

如不适配代码会导致编译报错，报错信息如下：

```ts
'"@kit.UserAuthenticationKit"' has no exported member named 'userAuthIcon'. Did you mean 'UserAuthIcon'? <ArkTSCheck>。
```

**该能力起始支持的API Level**

12

**变更的接口/组件**

@ohos.useriam.userAuthIcon

**适配指导**

```ts
import { userAuth, UserAuthIcon } from '@kit.UserAuthenticationKit';

@Entry
@Component
struct Index {
  authParam: userAuth.AuthParam = {
    challenge: new Uint8Array([49, 49, 49, 49, 49, 49]),
    authType: [userAuth.UserAuthType.FACE, userAuth.UserAuthType.PIN],
    authTrustLevel: userAuth.AuthTrustLevel.ATL3
  };
  widgetParam: userAuth.WidgetParam = {
    title: '请进行身份认证'
  };

  build() {
    Row() {
      Column() {
        UserAuthIcon({
          authParam: this.authParam,
          widgetParam: this.widgetParam,
          iconHeight: 200,
          iconColor: Color.Blue,
          onIconClick: () => {
            console.info('The user clicked the icon.');
          },
          onAuthResult: (result: userAuth.UserAuthResult) => {
            console.info('Get user auth result, result = ' + JSON.stringify(result));
          }
        })
      }
    }
  }
}
```

