DEV Community

陈杨
陈杨

Posted on

Treasure Case Sharing of HarmonyOS 5 Development — Application Concurrency Design

🌟 HarmonyOS Concurrent Programming Practical Guide: Unlocking ArkTS Multithreading Magic

Hey, developer friends! Today, let's dig into the treasure trove of concurrent programming hidden in the official HarmonyOS docs—100+ real-world scenario solutions! From financial apps to game development, from foldable screen adaptation to performance tuning, these cases are the hard-earned experience of Huawei engineers. Below, I'll use the most straightforward language + code samples to help you master HarmonyOS concurrent development!


🚀 1. ArkTS Concurrency Model: Disruptive Design

Pain Points of Traditional Models

graph LR  
A[Shared Memory Model] --> B[Thread + Lock Mechanism]  
B --> C[Large Number of Blocked Threads]  
C --> D[High Memory Usage / Scheduling Overhead]
Enter fullscreen mode Exit fullscreen mode

Typical Issue: Java apps often have hundreds of resident threads, I/O blocking causes lag

ArkTS's Breakthrough Solution

graph TB  
Main Thread --> |Message Communication| TaskPool Thread  
Main Thread --> |Bidirectional Communication| Worker Thread  
TaskPool Thread --> |System Managed| FFRT_I/O Pool[FFRT I/O Thread Pool]
Enter fullscreen mode Exit fullscreen mode

Three Core Concepts:

  1. Memory Isolation: Threads are forbidden from directly sharing objects
  2. Asynchronous I/O: The system automatically dispatches blocking operations to the background
  3. Auto Scaling: TaskPool dynamically adjusts the number of threads based on load

💡 Tested Comparison:

  • 8-core device thread count: Java averages 200+ vs ArkTS only 7-15
  • Memory usage: Empty Worker thread ≈ 2MB

🔥 2. High-Frequency Scenarios (with Code Analysis)

Scenario 1: Time-Consuming Task Concurrency—Image Decoding Acceleration

Pain Point: Decoding 4K images on the main thread causes UI freeze

// Step 1: Define concurrent function  
@Concurrent  
function decodeImage(imageData: ArrayBuffer): Image {  
  // Use native decoding library (does not block UI thread)  
  return nativeDecode(imageData);  
}  

// Step 2: Submit tasks to TaskPool  
function loadGallery() {  
  const imageTasks = imageList.map(img =>  
    taskpool.execute(decodeImage, img.rawData)  
  );  

  // Step 3: Batch get results  
  Promise.all(imageTasks).then(decodedImages => {  
    updateUI(decodedImages); // Render decoded images  
  });  
}
Enter fullscreen mode Exit fullscreen mode

Key Tips:

  • Single data transfer < 200KB (1ms transfer time)
  • Avoid passing complex objects (requires serialization)

Scenario 2: Foldable Screen Hover State—Video Player Adaptation

Effect: When half-folded, the video window automatically shrinks into the hover area

// Listen for fold status  
display.on('foldStatusChange', (status) => {  
  if (status === display.FoldStatus.HALF_FOLD) {  
    // Enter hover mode  
    videoPlayer.enterHoverMode().then(() => {  
      // Dynamically adjust layout  
      this.videoContainer.width = '30%';  
      this.videoContainer.margin = { top: 70, bottom: 10 };  
    });  
  }  
});  

// Video component encapsulation  
@Component  
struct VideoPlayer {  
  @State inHoverMode: boolean = false  

  enterHoverMode() {  
    this.inHoverMode = true  
    // Trigger picture-in-picture logic  
  }  
}
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Producer-Consumer Pattern—Reading App Preloading

Requirement: Pre-parse the next 5 pages in the background when turning pages

// Producer: Main thread submits parsing tasks  
function onPageTurn() {  
  for (let i=1; i<=5; i++) {  
    const task = new taskpool.Task(parsePage, nextPageData(i));  
    taskpool.execute(task).then(parsedPage => {  
      // Store result in cache queue  
      PageCache.enqueue(parsedPage);  
    });  
  }  
}  

// Consumer: Render page from cache  
@Concurrent  
function parsePage(rawData: PageData): Page {  
  // Complex parsing logic (time-consuming operation)  
  return new Page(rawData);  
}
Enter fullscreen mode Exit fullscreen mode

Concurrency Optimization Points:

  • Use taskpool.TaskGroup to manage tasks in batches
  • Priority setting: current page > next page > subsequent pages

3. Advanced Tips: Pitfall Avoidance Guide

Pitfall 1: Worker Thread Leaks

Incorrect Example:

// Not closing Worker leads to memory surge  
function processData() {  
  const worker = new worker.ThreadWorker('worker.js');  
  worker.postMessage(largeData);  
  // Forgot worker.terminate()!  
}
Enter fullscreen mode Exit fullscreen mode

Correct Solution:

worker.onmessage = () => {  
  // ...close immediately after processing  
  worker.terminate();   
}
Enter fullscreen mode Exit fullscreen mode

Pitfall 2: Modifying Shared Objects Across Threads

Dangerous Operation:

// Main thread  
const config = { theme: 'dark' };  
taskpool.execute(modifyConfig, config);  

@Concurrent  
function modifyConfig(cfg) {  
  cfg.theme = 'light'; // Throws exception!  
}
Enter fullscreen mode Exit fullscreen mode

Safe Solution:

// Use deep copy or freeze object  
const safeConfig = Object.freeze({ ...config });
Enter fullscreen mode Exit fullscreen mode

🛠️ 4. Performance Tuning Tools

1. Long List Lag Optimization

// Frame-by-frame rendering: process 50ms per frame  
@State @TrackItem items: Array<Item> = []  

loadData() {  
  for (let i=0; i<1000; i++) {  
    if (performance.now() - start > 50) {  
      setTimeout(this.loadData, 0) // Continue next frame  
      return  
    }  
    items.push(newItem)  
  }  
}  

// Component reuse  
@Component  
struct ListItem {  
  @TrackItem item: Item  

  aboutToReuse(params) {  
    this.item = params.item // Reuse instance  
  }  
}
Enter fullscreen mode Exit fullscreen mode

Tested Effect: Huawei Mate XT list FPS increased from 22→58

2. Memory Leak Detection

# Use HWAsan to detect native memory  
hdc shell setenforce 0  
hdc shell setprop hwaps.debug true
Enter fullscreen mode Exit fullscreen mode

Key Log Identifier:

[HWASAN] ERROR: heap-use-after-free
Enter fullscreen mode Exit fullscreen mode

💎 5. Summary: Best Practice Roadmap

journey  
  title HarmonyOS Concurrency Development Decision Tree  
  section Task Type  
    Short Task --> TaskPool: Image Decoding/JSON Parsing  
    Long Task --> Worker: Game Logic/Socket Listening  
  section Special Needs  
    Sequential Execution --> SequenceRunner  
    Dependency Management --> addDependency  
    Batch Processing --> TaskGroup
Enter fullscreen mode Exit fullscreen mode

One Last Word:

The concurrency model of HarmonyOS is designed for distributed systems. Once you master these cases, you'll find:

  • Foldable/multi-device adaptation is no longer a headache
  • Performance tuning has a clear path
  • Complex business logic is clearly decoupled

If you encounter pitfalls, feel free to discuss! If you find this useful, don't forget to like and bookmark 🌟


Top comments (0)