DEV Community

Cover image for [Learn HarmonyOS Next Knowledge Daily] SO Library Slimming, IDE Memory Configuration, Foreground/Background Detection
kouwei qing
kouwei qing

Posted on

[Learn HarmonyOS Next Knowledge Daily] SO Library Slimming, IDE Memory Configuration, Foreground/Background Detection

[Learn HarmonyOS Next Knowledge Daily] SO Library Slimming, IDE Memory Configuration, Foreground/Background Detection

1. How to Reduce the Size of Compiled SO Files?

When building with CMake commands, add CMake compilation parameters and C++ compiler parameters in CMakeLists.txt:

  1. Set the build type to Release, which disables debug information:
set(CMAKE_BUILD_TYPE Release)
Enter fullscreen mode Exit fullscreen mode
  1. -s strips symbol table information:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s")
Enter fullscreen mode Exit fullscreen mode

For integration in DevEco Studio IDE, configure compilation parameters and compiler parameters in externalnativeoptions:

The externalNativeOptions parameter in the module-level build-profile.json5 is the entry for compiling C/C++ files in NDK projects. You can specify the CMake script path via path, configure CMake parameters via arguments, set C++ compiler parameters via cppFlags, and configure compilation architectures via abiFilters:

"externalNativeOptions": {
  "path": "./src/main/cpp/CMakeLists.txt",
  "arguments": "-DCMAKE_BUILD_TYPE=Release",
  "cppFlags": "-s",
}
Enter fullscreen mode Exit fullscreen mode

2. How to Determine if an App is in the Foreground or Background?

Is there an API to determine foreground/background status, and are there callbacks when switching between them?

3. How to Adjust IDE Memory Size?

In Android Studio, org.gradle.jvmargs in gradle.properties sets the IDE memory size. Does DevEco have a similar configuration?

Modify the maxOldSpaceSize field in hvigor-config.json5 and increase it appropriately based on the project size (e.g., set to 8192):

"nodeOptions": {
  "maxOldSpaceSize": 8192
}
Enter fullscreen mode Exit fullscreen mode

4. How to Handle Tabs Nested with Web Sliding Scenarios?

When Tabs components are nested with Web components, the following issues may occur during scrolling:

  1. Vertical scrolling on the Web page mistakenly triggers Tab page swipe gestures.
  2. The Web component can still scroll vertically when switching Tabs.
  • Issue 1: Set the nested scroll property nestedScroll for the Web component.
  • Issue 2: Set the Web component's scroll permission via setScrollable.

Reference Code:

import web_webview from '@ohos.web.webview';
import business_error from '@ohos.base';

@Component
@Entry
struct TabWebPage2 {
  @State message: string = 'Hello World';
  private tabsController = new TabsController();
  private currentIndex: number = 0;
  private webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Vertical })
  // Control page switching via swiping
  @State flag: boolean = true
  build() {
    Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
      TabContent() {
        Web({ src: 'https://m.xxx.com/', controller: this.webviewController })// Set nested scrolling
          .nestedScroll({
            scrollForward: NestedScrollMode.PARENT_FIRST,
            scrollBackward: NestedScrollMode.SELF_FIRST
          })
      }.tabBar(this.tabBuilder('首页', 0))

      TabContent() {
        Column() {
          Text("发现")
        }.width('100%').height('100%')
      }.tabBar(this.tabBuilder('发现', 1))

      TabContent() {
        Column() {
          Text("推荐")
        }.width('100%').height('100%')
      }.tabBar(this.tabBuilder('推荐', 2))

      TabContent() {
        Column() {
          Text("我的")
        }.width('100%').height('100%')
      }
      .tabBar(this.tabBuilder('我的', 3))
    }
    .onChange((index: number) => {
      this.currentIndex = index;
    })
    .scrollable(this.flag)
    .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
    })
    .onAnimationEnd((index: number, event: TabsAnimationEvent) => {
      // Triggered when the switching animation ends; set the Web component to scrollable
      this.webviewController.setScrollable(true)
    })
    .onGestureSwipe((index: number, event: TabsAnimationEvent) => {
      // Triggered frame-by-frame during page swiping; set the Web page to non-scrollable when switching Tabs
      this.webviewController.setScrollable(false)
    })
  }

  @Builder
  tabBuilder(title: string, targetIndex: number) {
    Column() {
      Text(title)
        .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
    }
    .width('100%')
    .height(50)
    .justifyContent(FlexAlign.Center)
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Marquee Component Text Scrolling Shows Excessive Whitespace on the First Scroll. How to Avoid This?

When text in the Marquee component scrolls to the start of the control, it causes excessive whitespace. How can we make the text stop when the end of the text reaches the end of the control to avoid whitespace?

The Marquee currently does not support stopping at the end of the text. Use a Scroll component instead to achieve text scrolling.

Sample Code:

@Observed
class NewsTitle {
  public title: string

  constructor(title: string) {
    this.title = title;
  }
}

@Entry
@Component
struct Index {
  @State textList: string[] = [
    'this is a test string1 this is a test string1 this is a test string1',
    'this is a test string2 this is a test string2',
    'this is a test string3 this is a test string3 this is a test string3 this is a test string3',
  ]
  @State count: number = 1;

  build() {
    Row() {
      Column() {
        myMarqueeCard({
          textList: $textList,
          updateList: () => {
            this.textList = [
              `这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}`,
              `这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}`,
              `这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}这是测试数据${this.count++}`,
            ]
          }
        })
      }
      .width('100%')
      .margin(20)
    }
    .height('100%')
  }
}

class Tmp {
  text: string = ''
  scroller: Scroller = new Scroller()
}

@Component
struct myMarqueeCard {
  @Link @Watch('handleNewList') textList: string[]
  @State list: string[] = [];
  scroller1: Scroller = new Scroller()
  scroller2: Scroller = new Scroller()
  scroller3: Scroller = new Scroller()
  updateList?: () => void

  handleNewList() {
    console.log(JSON.stringify(this.textList))
  }

  build() {
    Column() {
      this.SingleText({ text: this.textList[0], scroller: this.scroller1 })
      this.SingleText({ text: this.textList[1], scroller: this.scroller2 })
      this.SingleText({ text: this.textList[2], scroller: this.scroller3 })
    }
  }

  @Builder
  SingleText($$: Tmp) {
    Scroll($$.scroller) {
      Row() {
        Text($$.text).fontSize(30).onAppear(() => {
          this.handleScroll($$.scroller)
        })
      }
    }
    .width(300)
    .scrollable(ScrollDirection.Horizontal)
    .enableScrollInteraction(false)
    .scrollBar(BarState.Off)

  }

  handleScroll(scroller: Scroller) {
    let timer: number = setInterval(() => {
      const curOffset: OffsetResult = scroller.currentOffset()
      scroller.scrollTo({
        xOffset: curOffset.xOffset + 50, yOffset: curOffset.yOffset, animation: {
          duration: 1000,
          curve: Curve.Linear
        }
      })
      if (scroller.isAtEnd()) {
        // clearInterval(timer);
        if (this.scroller1.isAtEnd() && this.scroller2.isAtEnd() && this.scroller3.isAtEnd()) {
          // Other operations
          if (this.updateList) {
            this.scroller1.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } })
            this.scroller2.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } })
            this.scroller3.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 0 } })
            this.updateList()
          }
        }
      }
    }, 500)
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)