[Huawei Developers] XDARoni:
Developing Your App

Code Development

Assume that there are eight tasks (tasks 0–7). Tasks 0–3 are executed concurrently. Task 4 is executed after the execution of tasks 0–3 is complete, and tasks 5-7 are executed in serial mode after task 4 is complete. The execution content is displayed in logs and can be customized based on service scenarios. The following is an example of multithread-lib for common usage.

1. This function collects statistics on exception logs and delay of multithread-lib for optimization. Before calling multithread-lib, include the multithread-lib header file, modify the source code file app/src/main/cpp/native-lib.cpp, and call dispatch_autostat_enable to enable the automatic statistics function.

#include <dispatch/dispatch.h>

Java_com_example_example_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */)
{
dispatch_autostat_enable(env);
}

Note: The argument is the Java operating environment (JNIEnv* env) in the thread. If the Java operating environment is not involved, the API is not available for your program. However, this does not affect usage of other functional APIs of multithread-lib.

2. In this way, the four tasks can be executed concurrently. Because tasks 0–3 need to be executed concurrently, call dispatch_queue_create to create a concurrent queue for task management. Alternatively, use the global queue predefined by multithread-lib. For details, please refer to the API Reference. Then, call dispatch_async to add tasks 0–3 to the concurrent queue.

int i;
dispatch_queue_t concurr_q = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
for (i = 0; i < 4; i++) {
dispatch_async(concurr_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "task %d is running in a concurrent queue", i);
});
}

4. Call dispatch_queue_create to create a serial queue for task management and puts tasks 4–7 to the serial queue in sequence. Then, call dispatch_async to execute the tasks based on the serial queue.

dispatch_queue_t serial_q = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
for (i = 4; i < 8; i++) {
dispatch_async(serial_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "task %d is running in a serial queue", i);
});
}

5. Call dispatch_release to release the created concurrent and serial queues.

dispatch_release(concurr_q);
dispatch_release(serial_q);

After the preceding configuration, your app should have been able to implement the multi-threading functions of multithread-lib. multithread-lib also provides other APIs, which can be flexibly combined to accommodate diverse multi-threading scenarios. For details, please refer to the API Reference. The complete code app/src/main/cpp/native-lib.cpp is as follows:

#include <jni.h>
#include <string>
#include <fcntl.h>
#include <android/log.h>
#include <dispatch/dispatch.h>

#define LOG_TAG "dispatch"

void dispatch_sample(void);

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_example_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */)
{
std::string hello = "Hello from C++ dispatch!";
dispatch_autostat_enable(env);
dispatch_sample();
return env->NewStringUTF(hello.c_str());
}

void dispatch_sample(void)
{
int i;
dispatch_queue_t concurr_q = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t serial_q = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);

for (i = 0; i < 4; i++) {
dispatch_async(concurr_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "task %d is running in a concurrent queue", i);
});
}

dispatch_barrier_sync(concurr_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "all tasks in the concurrent queue has finished");
});

for (i = 4; i < 8; i++) {
dispatch_async(serial_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "task %d is running in a serial queue", i);
});
}

dispatch_sync(serial_q, ^{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "all tasks in the serial queue has finished");
});

dispatch_release(concurr_q);
dispatch_release(serial_q);
}