Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

ArkTS and OpenHarmony Development Reference: Language Features and Runtime Behaviors

Tech 1

UI Builder Function Constraints in ArkTS

The build() method and custom builder functions operate under strict compilation rules to ensure predictable UI rendering. Expressions are restricted to string interpolation, conditional rendering, ForEach iterators, and component properties. Modifying application state variables (e.g., @State, @Prop, @Link) within these expressions is prohibited, as it triggers undefined framework behavior. Local variable declarations and arbitrary function invocations are also blocked inside the builder scope, except for event handlers like onClick.

build() {
  // let counter = 0; // Compilation error: local variables forbidden
  Column() {
    Text(`User: ${this.profile.name.toUpperCase()}`) // Valid interpolation
    // ForEach(this.items.sort(), ...) // Error: mutates @State array
    ForEach(this.items.slice(), (item: string) => {
      Text(item)
    })
    // this.runLogic(); // Error: direct calls not allowed
    Text(this.formatLabel()) // Valid: returns computed string
  }
}

Dynamic Placeholder Replacement in String Resources

Application resources referenced via $r() support runtime parameter injection. Pass additional arguments to $r() to replace %s tokens defined in the string.json configuration.

build() {
  Text($r('app.string.welcome_msg', 'Guest_User'))
    .fontSize(24)
    .fontColor('#000000')
}

Reading Raw Files and Converting to Strings

To process raw assets like XML configurations, retrieve the file as a Uint8Array through the resource manager, then decode it using standard JavaScript character conversion methods.

resourceManager.getRawFile('config/data.xml', (err, buffer) => {
  if (err) {
    console.error(`Failed to load asset: ${err.message}`);
    return;
  }
  const xmlContent = String.fromCharCode.apply(null, buffer);
  console.info(xmlContent);
});

Extracting String Values from Resource Objects

When a resource ID object is available, resolve its actual string value by invoking resourceManager.getString() with the resource identifier.

Static Class Properties vs. Global State

Pages and Abilities are bundled into isolated closures during compilation, resulting in separate global execution contexts. Consequently, static class properties do not share references across different UI modules. For cross-component state sharing, utilize AppStorage or LocalStorage instead of static class fields.

Resource Access via Context in Stage Model

The Stage architecture exposes a resourceManager instance directly through the UI context. This eliminates the need for explicit module imports when fetching localized assets.

const uiContext = getContext(this) as common.UIAbilityContext;
uiContext.resourceManager.getString($r('app.string.hello').id)
  .then((res) => {
    this.displayText = res;
  })
  .catch((err) => console.error(err));

Asynchronous Data Initialization Before Rendering

Trigger network requests or async operations inside the aboutToAppear lifecycle hook. Bind the result to a @State variable to automatically trigger UI updates once the data resolves.

@Entry
@Component
struct DataSyncView {
  @State statusText: string = 'Initializing...';

  aboutToAppear() {
    setTimeout(() => {
      this.statusText = 'Sync Complete';
    }, 2000);
  }

  build() {
    Column() {
      Text(this.statusText).fontSize(20)
    }.width('100%').height('100%')
  }
}

Worker Thread Execution Context

Background workers operate in isolated V8 instances separate from the main UI thread. Direct memory sharing is unsupported; all data exchange must occur via message passing APIs.

URI Encoding and Decoding

Standard global functions encodeURI() and decodeURI() handle URL-safe string transformation. Whitespace and special characters are converted to their percent-encoded equivalents (e.g., space becomes %20).

XML Document Parsing

Transform XML markup into traversable JavaScript objects using the convertXML.convert() utility provided by the framework.

Adaptive Application Icons

Leverage resource qualifiers to define multiple icon assets. The system automatically selects the appropriate resolution and theme variant based on device capabilities and user settings.

System Time Precision APIs

systemTime.getCurrentTime(false) aligns with new Date().getTime(), returning milliseconds since the Unix epoch. Passing true yields nanosecond precision. Both query the underlying system clock.

Typing Rules for @BuilderParam

When assigning a builder reference without invocation (e.g., slot: this.renderHeader), declare the property as a void function: @BuilderParam slot: () => void. If invoking with arguments during assignment (e.g., slot: this.renderHeader('title')), type the property as any to accommodate the evaluated result.

Worker Pool Limits and Cleanup

The runtime enforces a hard limit of seven concurrent worker instances per application. Exceeding this threshold throws a capacity exception. Always invoke worker.terminate() when background tasks complete to free execution slots.

Recommended Concurrency Model

For CPU-intensive operations or non-blocking I/O, the framework officially endorses the Worker API over traditional threading mechanisms to maintain UI responsiveness.

Component Re-instantiation in @Builder Methods

Decorated builder functions that instantiate custom components will generate fresh component instances on every invocation. This behavior differs from standard utility methods and impacts rendering performance if overused.

State Observation Depth and @Watch

The @Watch decorator monitors shallow reference changes only. Mutations to nested object properties or array elements do not trigger callbacks, mirroring the baseline behavior of @State.

Deep Reactive State Tracking

To observe mutations within complex objects or arrays, decorate the data model with @Observed and bind it to the UI using @ObjectLink. This enables granular change detection for nested structures.

Text Encoding and Decoding Utilities

Convert between byte streams and string representations using the TextEncoder and TextDecoder classes available in the util module.

Namespace Module Export Patterns

Group related utilities under a namespace and export them as a default module for cleaner imports.

namespace DateUtils {
  export function now(): number {
    return Date.now();
  }
}
export default DateUtils;
import DateUtils from './utils/date';
const timestamp = DateUtils.now();

Relational Database Access in Workers

RDB connection objects created on the main thread cannot be serialized or transferred to worker threads. Background tasks must initialize their own independent database connections using the relational store APIs.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.