DEV Community

Cover image for [Learn HarmonyOS Next Knowledge Every Day] About Performance, SO, etc.
kouwei qing
kouwei qing

Posted on

[Learn HarmonyOS Next Knowledge Every Day] About Performance, SO, etc.

[Learn HarmonyOS Next Knowledge Every Day] About Performance, SO, etc.

1. How to Compile Only Specified SO Libraries in the HAP Package During Compilation and Packaging?

To compile only specified SO libraries in the HAP package during compilation and packaging, configure in build-profile.json5:

// Configure filtering rules for .so resource files in HAR dependencies
"nativeLib": {
  "filter": {
    // Package the highest-priority .so files by priority order
    "pickFirsts": [
      "**/1.so"
    ],
    // Package the lowest-priority .so files by priority order
    "pickLasts": [
      "**/2.so"
    ],
    // Excluded .so files
    "excludes": [
      "**/3.so", // Exclude all .so files named "3"
      "**/x86_64/*.so" // Exclude all .so files for x86_64 architecture
    ],
    // Allow overriding lower-priority .so files with higher-priority ones when name conflicts occur
    "enableOverride": true
  }
}
Enter fullscreen mode Exit fullscreen mode

2. How to Convert a File into a String?

Convert files under rawfile into strings or Base64-formatted data for transmission:

getContext().resourceManager.getRawFileContent('MyStr.txt').then((value: Uint8Array) => {
  let textDecoder: util.TextDecoder = util.TextDecoder.create(); // Call the TextDecoder class from the util module
  let retStr: string = textDecoder.decodeWithStream(value); // Decode the Uint8Array
  let strBase64 = new util.Base64Helper().encodeToStringSync(value);
  console.info(retStr);
  console.info(strBase64);
}).catch((error: BusinessError) => {
  console.info('getRawFileContent promise error is ' + error);
});
Enter fullscreen mode Exit fullscreen mode

3. How to Analyze Component Performance?

How to know the time consumption of custom components in layout, rendering, and other stages to analyze component performance?

Performance Analysis Method 1:

  1. Use the following script to capture the trace:
hdc shell "mkdir -p /data/local/tmp"
hdc shell "bytrace -t 8 -b 32000 --overwrite sched ace app disk ohos graphic sync workq ability >/data/local/tmp/mynewtrace.ftrace"
hdc shell "sed -i '1,2d' /data/local/tmp/mynewtrace.ftrace"
hdc file recv /data/local/tmp/mynewtrace.ftrace .
Enter fullscreen mode Exit fullscreen mode
  1. Open the trace using the website https://ui.perfetto.dev/.
  2. Analysis steps:
    1. First locate the corresponding process.
    2. The image loading process is usually found on the bg thread, while the UI thread is the main thread where ArkUI's pipeline runs.

Performance Analysis Method 2: DevEco Profiler Tuning Tool

  1. In the Profiler main interface, select the "Frame" task type in the new task area and click "Create Session".
  2. Operate the APP on the tuning device, perform the operation to be verified, reproduce the performance issue, start task recording, and capture the trace for analysis.

4. How to Obtain the URI Address of a $rawfile in the Local Machine?

Reference code:

// Alternative solution: Use code to move the rawfile to be operated into the sandbox path, then execute related operations.
async function resourceFile(resourcePath: string) {
  // 1. Read the file
  let uint8Array: Uint8Array = getContext()
    .createModuleContext("library")
    .resourceManager
    .getRawFileContentSync(resourcePath);
  let fileName = resourcePath.substring(resourcePath.lastIndexOf('/') + 1);
  console.log("${tag} fileName:${fileName}");
  // 2. Create a sandbox file
  let filePath = getContext().createModuleContext("library").filesDir + '/' + fileName;
  if (fs.accessSync(filePath)) {
    fs.unlinkSync(filePath)
  }
  let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  // 3. Write the resource file to the sandbox file
  fs.writeSync(file.fd, uint8Array.buffer);
  // 4. Close the file
  fs.closeSync(file);
  console.log("${tag} filePath:${filePath}");
  return filePath;
}
Enter fullscreen mode Exit fullscreen mode

How to Handle Gesture Binding Conflicts with System Components That Have Default Built-in Gestures?

Currently, many system components with built-in gestures (such as List, Scroll, Menu, etc.) may experience conflicts after binding gesture events. Here are some related problem scenarios:

  1. When a Scroll component and a Gesture coexist, the Gesture becomes invalid.
  2. After binding a right-click menu to a component (triggered by long-press, ResponseType.LongPress), binding a LongPressGesture simultaneously prevents the right-click menu from being triggered.

For system components with default gesture events, binding new gestures can cause conflicts. This can be resolved by using the parallel gesture binding method (parallelGesture).

Reference code:

@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Up | PanDirection.Down })

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item: number) => {
            Text(item.toString())
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .margin({ top: 10 })
          }, (item: string) => item)
        }.width('100%')
      }
      .scrollable(ScrollDirection.Vertical) // Vertical scrolling direction
      .scrollBar(BarState.On) // Scrollbar always visible
      .scrollBarColor(Color.Gray) // Scrollbar color
      .scrollBarWidth(10) // Scrollbar width
      .friction(0.6)
      .edgeEffect(EdgeEffect.None)
      .onScroll((xOffset: number, yOffset: number) => {
        console.info(xOffset + ' ' + yOffset)
      })
      .onScrollEdge((side: Edge) => {
        console.info('To the edge')
      })
      .onScrollStop(() => {
        console.info('Scroll Stop')
      })
    }
    // Use parallel gesture binding (parallelGesture) to avoid conflicts with built-in gestures
    .parallelGesture(
      PanGesture(this.panOption)
        .onActionStart((event?: GestureEvent) => {
          console.info('Pan start', event)
        })
        .onActionUpdate((event?: GestureEvent) => {
          if (event) {
            console.info('Pan event', event)
          }
        })
        .onActionEnd(() => {
          console.info('Pan end')
        })
    )
    .width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)