Commit 7dbef7e8 authored by dsq's avatar dsq

第一次提交

parents
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
plugins {
// this is necessary to avoid the plugins to be loaded multiple times
// in each subproject's classloader
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
}
/**
能导入的包
1. 来源插件
在 当前的 build.gradle.kts 定义可以搭配的插件
plugins {
alias(libs.plugins.androidApplication) // 提供 android.* 相关类
alias(libs.plugins.kotlinMultiplatform) // 提供 org.jetbrains.kotlin.gradle.* 相关类
alias(libs.plugins.composeMultiplatform) // 提供 compose 相关类
}
插件的版本在 libs.versions.toml 中定义:
2.Gradle 核心类
Gradle 本身提供的核心类(如 Copy、JavaVersion 等)自动可用,无需额外配置
*/
// 导入大写工具(capitalizeUS),用于字符串首字母大写
import android.databinding.tool.ext.capitalizeUS
// 导入ExperimentalKotlinGradlePluginApi注解,用于开启Kotlin插件实验特性
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
// 导入JvmTarget,用于指定JVM的目标版本
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
// 应用Kotlin多平台插件
alias(libs.plugins.kotlinMultiplatform)
// 应用Android应用插件
alias(libs.plugins.androidApplication)
// 应用Compose多平台插件
alias(libs.plugins.composeMultiplatform)
// 应用Compose编译器插件
alias(libs.plugins.composeCompiler)
}
/**
Kotlin Multiplatform 配置
插件 libs.plugins.kotlinMultiplatform
负责 Kotlin 代码编译
Android: Kotlin/JVM → .class 文件 │
iOS: Kotlin/Native → LLVM IR │
OHOS: Kotlin/Native → LLVM IR
kotlin {
├── 目标平台 (androidTarget, jvm, iosX64, etc.)
│ ├── compilerOptions
│ └── binaries
├── cocoapods (iOS 特定)
├── sourceSets
│ ├── commonMain/commonTest
│ ├── platformMain/platformTest
│ └── customSourceSets
└── 其他配置
}
*/
kotlin {
// 配置Android目标
androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class) // 允许使用实验API
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11) // 设置JVM target为11
}
}
// 配置iOS三种架构目标
// 编译配置: Kotlin 源码 → LLVM IR -> 机器码
listOf(
iosX64(), // iOS 模拟器(x64架构)
iosArm64(), // iOS 真机(arm64架构)
iosSimulatorArm64() // iOS 模拟器(arm64架构)
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp" // 设置framework名称
// 静态库 (isStatic = true) - 代码直接嵌入到最终应用中
// 动态库 (isStatic = false) - 运行时加载的库
isStatic = true // 设置framework为静态库
}
}
// 配置OHOS(华为鸿蒙)arm64目标
ohosArm64 {
binaries.sharedLib {
baseName = "kn" // 共享库名称为kn
export(libs.compose.multiplatform.export) // 导出compose多平台库的接口
}
val main by compilations.getting // 获取主编译内容
// 添加devices库依赖 - 使用正确的Kotlin 2.2.21语法
compilations.named("main") {
compilerOptions.configure {
freeCompilerArgs.addAll(
listOf(
"-Xinclude-library=org.jetbrains.kotlin.native.platform.kba_devices",
"-Xdisable-default-klib-resolution"
)
)
}
}
}
// 配置各平台的依赖关系
sourceSets {
androidMain.dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.collection)
implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
commonMain.dependencies {
implementation(compose.runtime) // 添加compose runtime依赖
implementation(compose.foundation) // 添加compose基础依赖
implementation(compose.material) // 添加compose material依赖
implementation(compose.ui) // 添加compose ui依赖
implementation(compose.components.resources) // 添加compose组件资源依赖
implementation(compose.components.uiToolingPreview) // 添加compose ui工具预览依赖
implementation(libs.kotlinx.coroutines.core) // 官方协程核心库
implementation(libs.atomicFu) // Kotlin AtomicFu原子库
}
val ohosArm64Main by getting {
dependencies {
api(libs.compose.multiplatform.export) // 导出compose多平台接口给依赖消费者
}
}
}
}
/**
应用 AGP : Android Gradle Plugin
Android 应用构建 : .class → DEX(Dalvik 字节码) → APK │
由 androidApplication 插件提供
将 .class 文件转换为 DEX(Dalvik 字节码) 文件
Android 构建工具 → 打包成 APK
作用:
配置 Android 应用 的构建行为
控制 APK 生成、打包、签名等
*/
android {
namespace = "com.dong.demo013" // 设置包名
compileSdk = libs.versions.android.compileSdk.get().toInt() // 指定编译SDK版本
defaultConfig {
applicationId = "com.dong.demo013" // 应用ID
minSdk = libs.versions.android.minSdk.get().toInt() // 最低SDK版本
targetSdk = libs.versions.android.targetSdk.get().toInt()// 目标SDK版本
versionCode = 1 // 应用版本号
versionName = "1.0" // 应用版本名
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"// 排除打包时的冗余license资源文件
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false // 发布包不混淆代码
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11 // 源码兼容Java 11
targetCompatibility = JavaVersion.VERSION_11 // 输出兼容Java 11
}
}
dependencies {
debugImplementation(libs.compose.ui.tooling) // debug模式下依赖compose调试工具
}
// 为 ohosArm64 目标配置依赖处理
val versionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
val cmpVersion = versionCatalog.findVersion("composeMultiplatform")
.orElseThrow { IllegalStateException("Missing version composeMultiplatform in version catalog") }
.requiredVersion
val skikoOverrideByCmpVersion = mapOf(
"1.9.2-ez-001" to "0.9.22.2-ez-001",
// 仅在需要强制的 CMP 版本这里新增
)
val skikoOhosOverride = skikoOverrideByCmpVersion[cmpVersion]
configurations.all {
val configName = name
if (configName.contains("ohos", ignoreCase = true)) {
incoming.afterResolve {
val resolvedSkiko = resolutionResult.allComponents
.mapNotNull { it.moduleVersion }
.firstOrNull { it.group == "org.jetbrains.skiko" && it.name == "skiko" }
logger.lifecycle(
"Resolved skiko for $configName: " +
(resolvedSkiko?.let { "${it.group}:${it.name}:${it.version}" } ?: "not found")
)
}
// exclude(group = "org.jetbrains.androidx.lifecycle")
// exclude(group = "org.jetbrains.androidx.savedstate")
}
resolutionStrategy {
eachDependency {
// 如果是 skiko 依赖,检查配置名称是否包含 ohos
if (requested.group == "org.jetbrains.skiko" && requested.name == "skiko") {
if (configName.contains("ohos", ignoreCase = true)) {
skikoOhosOverride?.let { useVersion(it) }
}
}
// 强制指定 androidx.collection 版本,避免冲突
if (requested.group == "androidx.collection" && requested.name == "collection") {
useVersion(libs.versions.androidx.collection.get())
}
}
}
exclude(group = "androidx.collection", module = "collection-jvm")
}
// Harmony App 输出目录(支持命令行 --harmonyAppPath)
val harmonyAppDir: File = run {
val cliPath = project.findProperty("harmonyAppPath") as String?
if (cliPath.isNullOrBlank()) {
// 默认:项目根目录 /harmonyApp
rootProject.file("harmonyApp")
} else {
// 命令行传入的路径
file(cliPath)
}
}
// 字符串首字母大写工具函数
fun String.capitalizeUS(): String = this.replaceFirstChar {
if (it.isLowerCase()) it.titlecase() else it.toString()
}
// 为不同类型(debug、release)OHOS构建注册Copy任务并发布到Harmony App目录
arrayOf("debug", "release").forEach { type ->
tasks.register<Copy>("publish${type.capitalizeUS()}BinariesToHarmonyApp") {
group = "harmony" // 归类到harmony任务组
dependsOn("link${type.capitalizeUS()}SharedOhosArm64") // 依赖于OHOS shared lib的链接任务
into(harmonyAppDir) // 输出目标目录
from("build/bin/ohosArm64/${type}Shared/libkn_api.h") { // 复制头文件
into("entry/src/main/cpp/include/") // 指定目录
}
from(project.file("build/bin/ohosArm64/${type}Shared/libkn.so")) { // 复制共享库文件
into("/entry/libs/arm64-v8a/") // 指定目标目录
}
}
}
\ No newline at end of file
/**
能导入的包
1. 来源插件
在 当前的 build.gradle.kts 定义可以搭配的插件
plugins {
alias(libs.plugins.androidApplication) // 提供 android.* 相关类
alias(libs.plugins.kotlinMultiplatform) // 提供 org.jetbrains.kotlin.gradle.* 相关类
alias(libs.plugins.composeMultiplatform) // 提供 compose 相关类
}
插件的版本在 libs.versions.toml 中定义:
2.Gradle 核心类
Gradle 本身提供的核心类(如 Copy、JavaVersion 等)自动可用,无需额外配置
*/
// 导入大写工具(capitalizeUS),用于字符串首字母大写
import android.databinding.tool.ext.capitalizeUS
// 导入ExperimentalKotlinGradlePluginApi注解,用于开启Kotlin插件实验特性
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
// 导入JvmTarget,用于指定JVM的目标版本
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
// 应用Kotlin多平台插件
alias(libs.plugins.kotlinMultiplatform)
// 应用Android应用插件
alias(libs.plugins.androidApplication)
// 应用Compose多平台插件
alias(libs.plugins.composeMultiplatform)
// 应用Compose编译器插件
alias(libs.plugins.composeCompiler)
}
/**
Kotlin Multiplatform 配置
插件 libs.plugins.kotlinMultiplatform
负责 Kotlin 代码编译
Android: Kotlin/JVM → .class 文件 │
iOS: Kotlin/Native → LLVM IR │
OHOS: Kotlin/Native → LLVM IR
kotlin {
├── 目标平台 (androidTarget, jvm, iosX64, etc.)
│ ├── compilerOptions
│ └── binaries
├── cocoapods (iOS 特定)
├── sourceSets
│ ├── commonMain/commonTest
│ ├── platformMain/platformTest
│ └── customSourceSets
└── 其他配置
}
*/
kotlin {
// 配置Android目标
androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class) // 允许使用实验API
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11) // 设置JVM target为11
}
}
targets.all {
compilations.all {
kotlinOptions {
freeCompilerArgs += listOf("-Xdisable-default-klib-resolution")
}
}
}
---
kotlin {
// 配置Android目标
androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class) // 允许使用实验API
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11) // 设置JVM target为11
}
}
targets.all {
compilations.all {
kotlinOptions {
freeCompilerArgs += listOf("-Xdisable-default-klib-resolution")
}
}
}
// 配置iOS三种架构目标
// 编译配置: Kotlin 源码 → LLVM IR -> 机器码
listOf(
iosX64(), // iOS 模拟器(x64架构)
iosArm64(), // iOS 真机(arm64架构)
iosSimulatorArm64() // iOS 模拟器(arm64架构)
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp" // 设置framework名称
// 静态库 (isStatic = true) - 代码直接嵌入到最终应用中
// 动态库 (isStatic = false) - 运行时加载的库
isStatic = true // 设置framework为静态库
}
}
// 配置OHOS(华为鸿蒙)arm64目标
ohosArm64 {
binaries.sharedLib {
baseName = "kn" // 共享库名称为kn
export(libs.compose.multiplatform.export) // 导出compose多平台库的接口
}
val main by compilations.getting // 获取主编译内容
val resource by main.cinterops.creating {
// 配置C interop(cinterop)资源
defFile(file("src/ohosArm64Main/cinterop/resource.def")) // cinterop定义文件
includeDirs(file("src/ohosArm64Main/cinterop/include")) // cinterop包含目录
}
// 添加devices库依赖
compilations.named("main") {
kotlinOptions {
freeCompilerArgs += listOf(
"-Xinclude-library=org.jetbrains.kotlin.native.platform.kba_devices"
)
}
}
}
// 配置各平台的依赖关系
sourceSets {
androidMain.dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.collection)
implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
commonMain.dependencies {
implementation(compose.runtime) // 添加compose runtime依赖
implementation(compose.foundation) // 添加compose基础依赖
implementation(compose.material) // 添加compose material依赖
implementation(compose.ui) // 添加compose ui依赖
implementation(compose.components.resources) // 添加compose组件资源依赖
implementation(compose.components.uiToolingPreview) // 添加compose ui工具预览依赖
implementation(libs.kotlinx.coroutines.core) // 官方协程核心库
implementation(libs.atomicFu) // Kotlin AtomicFu原子库
}
val ohosArm64Main by getting {
dependencies {
api(libs.compose.multiplatform.export) // 导出compose多平台接口给依赖消费者
}
}
}
}
/**
应用 AGP : Android Gradle Plugin
Android 应用构建 : .class → DEX(Dalvik 字节码) → APK │
由 androidApplication 插件提供
将 .class 文件转换为 DEX(Dalvik 字节码) 文件
Android 构建工具 → 打包成 APK
作用:
配置 Android 应用 的构建行为
控制 APK 生成、打包、签名等
*/
android {
namespace = "com.dong.demo013" // 设置包名
compileSdk = libs.versions.android.compileSdk.get().toInt() // 指定编译SDK版本
defaultConfig {
applicationId = "com.dong.demo013" // 应用ID
minSdk = libs.versions.android.minSdk.get().toInt() // 最低SDK版本
targetSdk = libs.versions.android.targetSdk.get().toInt()// 目标SDK版本
versionCode = 1 // 应用版本号
versionName = "1.0" // 应用版本名
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"// 排除打包时的冗余license资源文件
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false // 发布包不混淆代码
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11 // 源码兼容Java 11
targetCompatibility = JavaVersion.VERSION_11 // 输出兼容Java 11
}
}
dependencies {
debugImplementation(libs.compose.ui.tooling) // debug模式下依赖compose调试工具
}
// 为 ohosArm64 目标配置依赖处理
val versionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
val cmpVersion = versionCatalog.findVersion("composeMultiplatform")
.orElseThrow { IllegalStateException("Missing version composeMultiplatform in version catalog") }
.requiredVersion
val skikoOverrideByCmpVersion = mapOf(
"1.9.2-ez-001" to "0.9.22.2-ez-001",
// 仅在需要强制的 CMP 版本这里新增
)
val skikoOhosOverride = skikoOverrideByCmpVersion[cmpVersion]
configurations.all {
val configName = name
if (configName.contains("ohos", ignoreCase = true)) {
incoming.afterResolve {
val resolvedSkiko = resolutionResult.allComponents
.mapNotNull { it.moduleVersion }
.firstOrNull { it.group == "org.jetbrains.skiko" && it.name == "skiko" }
logger.lifecycle(
"Resolved skiko for $configName: " +
(resolvedSkiko?.let { "${it.group}:${it.name}:${it.version}" } ?: "not found")
)
}
// exclude(group = "org.jetbrains.androidx.lifecycle")
// exclude(group = "org.jetbrains.androidx.savedstate")
}
resolutionStrategy {
eachDependency {
// 如果是 skiko 依赖,检查配置名称是否包含 ohos
if (requested.group == "org.jetbrains.skiko" && requested.name == "skiko") {
if (configName.contains("ohos", ignoreCase = true)) {
skikoOhosOverride?.let { useVersion(it) }
}
}
// 强制指定 androidx.collection 版本,避免冲突
if (requested.group == "androidx.collection" && requested.name == "collection") {
useVersion(libs.versions.androidx.collection.get())
}
}
}
exclude(group = "androidx.collection", module = "collection-jvm")
}
// Harmony App 输出目录(支持命令行 --harmonyAppPath)
val harmonyAppDir: File = run {
val cliPath = project.findProperty("harmonyAppPath") as String?
if (cliPath.isNullOrBlank()) {
// 默认:项目根目录 /harmonyApp
rootProject.file("harmonyApp")
} else {
// 命令行传入的路径
file(cliPath)
}
}
// 字符串首字母大写工具函数
fun String.capitalizeUS(): String = this.replaceFirstChar {
if (it.isLowerCase()) it.titlecase() else it.toString()
}
// 为不同类型(debug、release)OHOS构建注册Copy任务并发布到Harmony App目录
arrayOf("debug", "release").forEach { type ->
tasks.register<Copy>("publish${type.capitalizeUS()}BinariesToHarmonyApp") {
group = "harmony" // 归类到harmony任务组
dependsOn("link${type.capitalizeUS()}SharedOhosArm64") // 依赖于OHOS shared lib的链接任务
into(harmonyAppDir) // 输出目标目录
from("build/bin/ohosArm64/${type}Shared/libkn_api.h") { // 复制头文件
into("entry/src/main/cpp/include/") // 指定目录
}
from(project.file("build/bin/ohosArm64/${type}Shared/libkn.so")) { // 复制共享库文件
into("/entry/libs/arm64-v8a/") // 指定目标目录
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package com.dong.demo013
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.Composable
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
App()
}
}
}
package com.dong.demo013
import android.os.Build
class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
internal actual fun getPlatformDemoList(): List<PlatformDemoItem> = emptyList()
@androidx.compose.runtime.Composable
internal actual fun PlatformDemo(id: String) {
}
package com.dong.demo013
actual fun createTimer(): TimerController {
TODO("Not yet implemented")
}
actual fun startLog(
speed: Int,
onLogGenerated: ((Int) -> Unit)?,
onTimerUpdated: ((Long) -> Unit)?
): LogController {
TODO("Not yet implemented")
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
<resources>
<string name="app_name">Demo</string>
</resources>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="450dp"
android:height="450dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M56.25,18V46L32,60 7.75,46V18L32,4Z"
android:fillColor="#6075f2"/>
<path
android:pathData="m41.5,26.5v11L32,43V60L56.25,46V18Z"
android:fillColor="#6b57ff"/>
<path
android:pathData="m32,43 l-9.5,-5.5v-11L7.75,18V46L32,60Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="23.131"
android:centerY="18.441"
android:gradientRadius="42.132"
android:type="radial">
<item android:offset="0" android:color="#FF5383EC"/>
<item android:offset="0.867" android:color="#FF7F52FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M22.5,26.5 L32,21 41.5,26.5 56.25,18 32,4 7.75,18Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="44.172"
android:startY="4.377"
android:endX="17.973"
android:endY="34.035"
android:type="linear">
<item android:offset="0" android:color="#FF33C3FF"/>
<item android:offset="0.878" android:color="#FF5383EC"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m32,21 l9.526,5.5v11L32,43 22.474,37.5v-11z"
android:fillColor="#000000"/>
</vector>
package com.dong.demo013
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.dong.demo013.demos.Log.TestLogDemo
import com.dong.demo013.navigation.ComponentDemo
import com.dong.demo013.navigation.ComposeGroup
import com.dong.demo013.navigation.Page
@Composable
internal fun App() {
MaterialTheme {
// 使用 Page 类型的状态,修复类型推断报错
var page by remember { mutableStateOf<Page>(Page.Home) }
when (val p = page) {
is Page.Home -> {
HomeScreen(
onSelect = { demo ->
page = Page.Detail(demo)
}
)
}
is Page.Detail -> {
DemoScreen(demo = p.demo, onBack = { page = Page.Home })
}
}
}
}
@Composable
internal fun HomeScreen(
onSelect: (ComponentDemo) -> Unit
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 第一个模块:嵌套页面
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 8.dp,
shape = RoundedCornerShape(12.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = "嵌套页面",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(bottom = 12.dp)
)
// 示例内容
Card(
backgroundColor = MaterialTheme.colors.primary.copy(alpha = 0.1f),
modifier = Modifier.fillMaxWidth()
) {
Column(modifier = Modifier.padding(12.dp)) {
Text("这是一个嵌套页面示例", style = MaterialTheme.typography.body1)
Spacer(Modifier.height(8.dp))
Text("可以展示一些基础的UI组件和交互效果",
style = MaterialTheme.typography.caption,
color = MaterialTheme.colors.onSurface.copy(alpha = 0.7f))
}
}
}
}
// 第二个模块:日志测试
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 8.dp,
shape = RoundedCornerShape(12.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = "日志测试",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(bottom = 12.dp)
)
// 日志测试按钮区域
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = {
val logDemo = ComponentDemo(
id = "log_test_demo",
title = "日志测试演示",
group = ComposeGroup.Foundation
)
onSelect(logDemo)
},
modifier = Modifier.fillMaxWidth()
) {
Text("进入日志测试")
}
}
}
}
// 第三个模块:大体积包
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 8.dp,
shape = RoundedCornerShape(12.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = "大体积包",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(bottom = 12.dp)
)
// 占位内容
Text(
text = "大体积包内容区域",
style = MaterialTheme.typography.body1,
color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
)
}
}
}
}
@Composable
internal fun DemoScreen(
demo: ComponentDemo,
onBack: () -> Unit
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
// 返回按钮
Button(
onClick = onBack,
modifier = Modifier.padding(bottom = 16.dp)
) {
Text("返回首页")
}
// 根据 demo.id 显示对应的内容
when (demo.id) {
"log_test_demo" -> {
TestLogDemo()
}
else -> {
Text(
text = "暂未实现: ${demo.title}",
style = MaterialTheme.typography.h6
)
}
}
}
}
\ No newline at end of file
package com.dong.demo013
class Greeting {
private val platform = getPlatform()
fun greet(): String {
return "Hello, ${platform.name}!"
}
}
\ No newline at end of file
package com.dong.demo013
interface LogController {
fun stop()
val isRunning: Boolean
}
\ No newline at end of file
package com.dong.demo013
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
internal data class PlatformDemoItem(val id: String, val title: String)
internal expect fun getPlatformDemoList(): List<PlatformDemoItem>
@androidx.compose.runtime.Composable
internal expect fun PlatformDemo(id: String)
package com.dong.demo013
expect fun startLog(speed: Int, onLogGenerated: ((Int) -> Unit)? = null, onTimerUpdated: ((Long) -> Unit)? = null): LogController
// 创建独立的计时器控制器
expect fun createTimer(): TimerController
\ No newline at end of file
package com.dong.demo013
interface TimerController {
fun start()
fun stop()
fun reset()
val isRunning: Boolean
val elapsedTime: Long
}
\ No newline at end of file
package com.dong.demo013.demos.Log
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.dong.demo013.LogController
import com.dong.demo013.TimerController
import com.dong.demo013.createTimer
import com.dong.demo013.startLog
import kotlinx.coroutines.delay
@OptIn(ExperimentalLayoutApi::class)
@Composable
internal fun TestLogDemo() {
// 日志参数状态
var logSpeed by remember { mutableStateOf("100") }
var logCount by remember { mutableStateOf(0) }
var isGenerating by remember { mutableStateOf(false) }
var logController by remember { mutableStateOf<LogController?>(null) }
// 计时器状态
var timerController by remember { mutableStateOf<TimerController?>(null) }
var displayTime by remember { mutableStateOf(0L) }
// 初始化计时器
LaunchedEffect(Unit) {
timerController = createTimer()
}
// 定期更新显示时间
LaunchedEffect(timerController) {
while (true) {
delay(100) // 每100ms更新一次显示
displayTime = timerController?.elapsedTime ?: 0
}
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 计时器显示区域
Card(backgroundColor = MaterialTheme.colors.surface) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
"运行时间",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(bottom = 12.dp)
)
// 时间显示
Card(
backgroundColor = MaterialTheme.colors.primary.copy(alpha = 0.1f),
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"${displayTime}秒",
style = MaterialTheme.typography.h4,
color = MaterialTheme.colors.primary
)
if (isGenerating) {
Text(
"日志生成中...",
style = MaterialTheme.typography.caption,
color = MaterialTheme.colors.secondary
)
}
}
}
}
}
// 日志生成功能区域
Card(backgroundColor = MaterialTheme.colors.surface) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
"日志生成工具",
style = MaterialTheme.typography.h6,
modifier = Modifier.padding(bottom = 12.dp)
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
value = logSpeed,
onValueChange = { newValue ->
// 只允许数字输入
if (newValue.all { it.isDigit() }) {
logSpeed = newValue
}
},
label = { Text("间隔(ms)") },
modifier = Modifier.weight(1f),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
singleLine = true
)
}
Spacer(Modifier.height(12.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = {
val speed = logSpeed.toIntOrNull() ?: 100
logCount = 0
// 重置并启动计时器
timerController?.reset()
timerController?.start()
// 启动日志生成
isGenerating = true
logController = startLog(speed,
onLogGenerated = { count ->
logCount = count
},
onTimerUpdated = { time ->
// 日志生成的计时现在只用于内部统计,不更新UI
}
)
},
modifier = Modifier.weight(1f),
enabled = logSpeed.isNotEmpty() && !isGenerating
) {
Text("开始生成")
}
Button(
onClick = {
logController?.stop()
timerController?.stop()
isGenerating = false
},
modifier = Modifier.weight(1f),
enabled = isGenerating
) {
Text("停止生成")
}
}
// 显示日志生成状态
if (isGenerating || logCount > 0) {
Spacer(Modifier.height(12.dp))
Card(
backgroundColor = MaterialTheme.colors.secondary.copy(alpha = 0.1f),
modifier = Modifier.fillMaxWidth()
) {
Column(
modifier = Modifier.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"生成日志数量",
style = MaterialTheme.typography.subtitle1,
color = MaterialTheme.colors.secondary
)
Text(
"$logCount 条",
style = MaterialTheme.typography.h4,
color = MaterialTheme.colors.secondary,
modifier = Modifier.padding(top = 4.dp)
)
}
}
}
}
}
}
}
\ No newline at end of file
package com.dong.demo013.navigation
enum class ComposeGroup {
Ui, Foundation, Material, Benchmark, Platform
}
data class ComponentDemo(
val id: String,
val title: String,
val group: ComposeGroup
)
val componentDemos: List<ComponentDemo> = listOf(
// ui
ComponentDemo("ui_box", "Box", ComposeGroup.Ui),
// foundation
ComponentDemo("foundation_basic_text", "BasicText", ComposeGroup.Foundation),
ComponentDemo("foundation_lazy_column", "LazyColumn", ComposeGroup.Foundation),
// log
ComponentDemo("log_test_demo", "日志测试演示", ComposeGroup.Foundation),
// material 组:新增完整清单
ComponentDemo("material_alert_dialog", "AlertDialogSample", ComposeGroup.Material),
ComponentDemo("material_app_bar", "AppBarSamples", ComposeGroup.Material),
ComponentDemo("material_backdrop_scaffold", "BackdropScaffoldSamples", ComposeGroup.Material),
ComponentDemo("material_badge", "BadgeSamples", ComposeGroup.Material),
ComponentDemo("material_bottom_navigation", "BottomNavigationSamples", ComposeGroup.Material),
ComponentDemo("material_bottom_sheet_scaffold", "BottomSheetScaffoldSamples", ComposeGroup.Material),
ComponentDemo("material_button_samples", "ButtonSamples", ComposeGroup.Material),
ComponentDemo("material_card_samples", "CardSamples", ComposeGroup.Material),
ComponentDemo("material_chip_samples", "ChipSamples", ComposeGroup.Material),
ComponentDemo("material_content_alpha", "ContentAlphaSamples", ComposeGroup.Material),
ComponentDemo("material_drawer_samples", "DrawerSamples", ComposeGroup.Material),
ComponentDemo("material_elevation_samples", "ElevationSamples", ComposeGroup.Material),
ComponentDemo("material_exposed_dropdown_menu", "ExposedDropdownMenuSamples", ComposeGroup.Material),
ComponentDemo("material_fab_samples", "FloatingActionButtonSamples", ComposeGroup.Material),
ComponentDemo("material_icon_button_samples", "IconButtonSamples", ComposeGroup.Material),
ComponentDemo("material_list_samples", "ListSamples", ComposeGroup.Material),
ComponentDemo("material_menu_samples", "MenuSamples", ComposeGroup.Material),
ComponentDemo("material_modal_bottom_sheet", "ModalBottomSheetSamples", ComposeGroup.Material),
ComponentDemo("material_navigation_rail", "NavigationRailSample", ComposeGroup.Material),
ComponentDemo("material_progress_indicator", "ProgressIndicatorSamples", ComposeGroup.Material),
ComponentDemo("material_pull_refresh", "PullRefreshSamples", ComposeGroup.Material),
ComponentDemo("material_scaffold_samples", "ScaffoldSamples", ComposeGroup.Material),
ComponentDemo("material_selection_controls", "SelectionControlsSamples", ComposeGroup.Material),
ComponentDemo("material_slider_sample", "SliderSample", ComposeGroup.Material),
ComponentDemo("material_surface_samples", "SurfaceSamples", ComposeGroup.Material),
ComponentDemo("material_swipeable_samples", "SwipeableSamples", ComposeGroup.Material),
ComponentDemo("material_swipe_to_dismiss", "SwipeToDismissSamples", ComposeGroup.Material),
ComponentDemo("material_tab_samples", "TabSamples", ComposeGroup.Material),
ComponentDemo("material_text_field_samples", "TextFieldSamples", ComposeGroup.Material),
ComponentDemo("material_text_samples", "TextSamples", ComposeGroup.Material),
ComponentDemo("material_theme_samples", "ThemeSamples", ComposeGroup.Material),
// benchmark
ComponentDemo("benchmark_1500_text", "1500 Text", ComposeGroup.Benchmark),
ComponentDemo("benchmark_1500_view", "1500 View", ComposeGroup.Benchmark),
)
val groupTitles: Map<ComposeGroup, String> = mapOf(
ComposeGroup.Ui to "compose.ui",
ComposeGroup.Foundation to "compose.foundation",
ComposeGroup.Material to "compose.material",
ComposeGroup.Platform to "Platform",
)
fun demosByGroup(): Map<ComposeGroup, List<ComponentDemo>> {
val standardDemos = ComposeGroup.entries.filter { it != ComposeGroup.Platform }
.associateWith { g -> componentDemos.filter { it.group == g } }
.toMutableMap()
val platformDemos = com.dong.demo013.getPlatformDemoList().map {
ComponentDemo(
id = it.id,
title = it.title,
group = ComposeGroup.Platform
)
}
if (platformDemos.isNotEmpty()) {
standardDemos[ComposeGroup.Platform] = platformDemos
}
return standardDemos
}
fun demosJson(): String = buildString {
append('[')
componentDemos.forEachIndexed { index, demo ->
if (index > 0) append(',')
append("{\"id\":\"")
append(jsonEscape(demo.id))
append("\",\"title\":\"")
append(jsonEscape(demo.title))
append("\",\"group\":\"")
append(demo.group.name)
append("\"}")
}
append(']')
}
fun groupTitlesJson(): String = buildString {
append('{')
ComposeGroup.entries.forEachIndexed { index, group ->
if (index > 0) append(',')
append('"')
append(group.name)
append("\":\"")
append(jsonEscape(groupTitles[group] ?: group.name))
append('"')
}
append('}')
}
private fun jsonEscape(input: String): String = buildString(input.length) {
input.forEach { ch ->
when (ch) {
'\\' -> append("\\\\")
'"' -> append("\\\"")
'\n' -> append("\\n")
'\r' -> append("\\r")
'\t' -> append("\\t")
else -> append(ch)
}
}
}
sealed interface Page {
data object Home : Page
data class Detail(val demo: ComponentDemo) : Page
}
package com.dong.demo013
import kotlin.test.Test
import kotlin.test.assertEquals
class ComposeAppCommonTest {
@Test
fun example() {
assertEquals(3, 1 + 2)
}
}
\ No newline at end of file
package com.dong.demo013
import androidx.compose.ui.window.ComposeUIViewController
fun MainViewController() = ComposeUIViewController { App() }
package com.dong.demo013
import platform.UIKit.UIDevice
class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
internal actual fun getPlatformDemoList(): List<PlatformDemoItem> = emptyList()
@androidx.compose.runtime.Composable
internal actual fun PlatformDemo(id: String) {
}
\ No newline at end of file
package com.dong.demo013
actual fun createTimer(): TimerController {
TODO("Not yet implemented")
}
actual fun startLog(
speed: Int,
onLogGenerated: ((Int) -> Unit)?,
onTimerUpdated: ((Long) -> Unit)?
): LogController {
TODO("Not yet implemented")
}
\ No newline at end of file
#ifndef GLOBAL_RAW_FILE_H
#define GLOBAL_RAW_FILE_H
#ifdef __cplusplus
extern "C" {
#endif
struct RawFile;
typedef struct RawFile RawFile;
int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length);
long OH_ResourceManager_GetRawFileSize(RawFile *rawFile);
void OH_ResourceManager_CloseRawFile(RawFile *rawFile);
#ifdef __cplusplus
};
#endif
/** @} */
#endif // GLOBAL_RAW_FILE_H
#ifndef GLOBAL_NATIVE_RESOURCE_MANAGER_H
#define GLOBAL_NATIVE_RESOURCE_MANAGER_H
#include "napi/native_api.h"
#include "raw_file.h"
#ifdef __cplusplus
extern "C" {
#endif
struct NativeResourceManager;
typedef struct NativeResourceManager NativeResourceManager;
NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr);
void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr);
RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName);
#ifdef __cplusplus
};
#endif
/** @} */
#endif // GLOBAL_NATIVE_RESOURCE_MANAGER_H
package = platform.resource
headers = raw_file_manager.h raw_file.h
depends = platform.kba_devices
---
package = platform.resource
headers = raw_file_manager.h raw_file.h
depends = platform.kba_devices
compilerOpts = -I/Users/dongsq/.konan/dependencies/sysroot-ohos-aarch64-15/usr/include
\ No newline at end of file
package com.dong.demo013
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.arkui.ArkUIView
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.interop.AdaptiveParams
import androidx.compose.ui.interop.InteropContainer
import androidx.compose.ui.napi.JsObject
import androidx.compose.ui.napi.js
private val NoOp: Any.() -> Unit = {}
@Composable
internal fun ArkUIView(
name: String,
modifier: Modifier,
parameter: JsObject = js(),
update: (JsObject) -> Unit = NoOp,
background: Color = Color.Unspecified,
updater: (ArkUIView) -> Unit = NoOp,
onCreate: (ArkUIView) -> Unit = NoOp,
onRelease: (ArkUIView) -> Unit = NoOp,
interactive: Boolean = true,
adaptiveParams: AdaptiveParams? = null,
tag: String? = null,
container: InteropContainer = InteropContainer.BACK
) = androidx.compose.ui.interop.ArkUIView(
name = name,
modifier = modifier,
parameter = parameter,
update = update,
background = background,
updater = updater,
onCreate = onCreate,
onRelease = onRelease,
interactive = interactive,
adaptiveParams = adaptiveParams,
tag = tag,
container = container,
)
package com.dong.demo013
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.napi.js
import androidx.compose.ui.unit.dp
@Composable
internal fun InteropListNested() {
LazyColumn(Modifier.fillMaxSize()) {
items(20) { index ->
when {
index == 3 -> {
// Nested Vertical List (ArkUI)
ArkUIView(
name = "verticalList",
modifier = Modifier.fillMaxWidth().height(300.dp).background(Color.LightGray),
parameter = js { }
)
}
index == 7 -> {
// Horizontal List (ArkUI) - assuming horizontalList exists and works similar
ArkUIView(
name = "horizontalList",
modifier = Modifier.fillMaxWidth().height(150.dp).background(Color.LightGray),
parameter = js { }
)
}
index % 3 == 0 -> {
// Button (ArkUI)
ArkUIView(
name = "button",
modifier = Modifier.fillMaxWidth().height(60.dp),
parameter = js {
"text"("ArkUI Button $index")
"backgroundColor"("#FF0000FF")
}
)
}
else -> {
// Compose Text
Text("Compose Item $index", Modifier.padding(16.dp))
}
}
}
}
}
package com.dong.demo013
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.napi.js
import androidx.compose.ui.unit.dp
@Composable
internal fun InteropListSimple() {
Box {
Column(Modifier.background(Color.LightGray).fillMaxSize()) {
LazyColumn(Modifier.background(Color.Red).fillMaxSize()) {
items(80) { index ->
Column {
ArkUIView(
name = "label",
modifier = Modifier.width(250.dp).height(100.dp),
parameter = js {
"text"("ArkUI Button $index")
"backgroundColor"("#FF0000FF")
},
)
Button({
println("Compose Button $index clicked")
}, modifier = Modifier.height(30.dp).fillMaxWidth()) {
Text("Compose Button $index")
}
}
}
}
}
}
}
package com.dong.demo013
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.napi.js
import androidx.compose.ui.unit.dp
@Composable
internal fun InteropRenderOrder() {
var interLayer by remember { mutableStateOf(false) }
Column {
Box {
ArkUIView(
"layer", Modifier.width(400.dp).height(300.dp),
js {
"text"("1")
"backgroundColor"("#FF0000FF")
},
)
ArkUIView(
"layer", Modifier.width(350.dp).height(250.dp),
js {
"text"("2")
"backgroundColor"("#FF00FF00")
},
)
if (interLayer) {
ArkUIView(
"layer", Modifier.width(300.dp).height(200.dp),
js {
"text"("3")
"backgroundColor"("#FFFF0000")
},
)
}
ArkUIView(
"layer", Modifier.width(250.dp).height(150.dp),
js {
"text"("4")
"backgroundColor"("#FF00FFFF")
},
)
ArkUIView(
"layer", Modifier.width(200.dp).height(100.dp),
js {
"text"("5")
"backgroundColor"("#FFFFFF00")
},
)
}
Button({ interLayer = !interLayer }) {
Text("Show / Hide")
}
}
}
package com.dong.demo013
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.napi.asString
import androidx.compose.ui.napi.js
import androidx.compose.ui.unit.dp
import kotlinx.cinterop.ExperimentalForeignApi
@OptIn(ExperimentalForeignApi::class)
@Composable
internal fun InteropTextInput() {
Column(
Modifier
.fillMaxWidth()
.fillMaxHeight()
.verticalScroll(rememberScrollState())
.padding(30.dp)
) {
var inputText by remember { mutableStateOf("混排状态变量双向通信 输入文本...") }
val state = remember(inputText) {
js { "text"(inputText) }
}
ArkUIView(
name = "textInput",
modifier = Modifier.width(450.dp).wrapContentHeight(),
parameter = state,
update = {
inputText = it["text"].asString().toString()
}
)
Spacer(modifier = Modifier.height(50.dp))
Text(text = "Compose组件更新:", color = Color.Gray)
Text(
text = inputText,
modifier = Modifier.fillMaxWidth()
.border(width = 1.dp, color = Color.Gray)
.padding(10.dp)
)
Button(onClick = { inputText += "[文本]" }) {
Text("Append Text")
}
}
}
package com.dong.demo013
import kotlinx.atomicfu.AtomicBoolean
import kotlinx.atomicfu.atomic
class LogControllerImpl : LogController {
private val _isRunning = atomic(true)
override val isRunning: Boolean
get() = _isRunning.value
override fun stop() {
_isRunning.value = false
}
}
\ No newline at end of file
package com.dong.demo013
import androidx.compose.ui.window.ComposeArkUIViewController
import com.dong.demo013.navigation.ComponentDemo
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.coroutines.initMainHandler
import platform.ohos.napi_env
import platform.ohos.napi_value
import kotlin.experimental.ExperimentalNativeApi
@OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)
@CName("MainArkUIViewController")
fun MainArkUIViewController(env: napi_env): napi_value {
initMainHandler(env)
return ComposeArkUIViewController(env) {
App()
}
}
package com.dong.demo013
class OhosPlatform : Platform {
override val name: String = "HarmonyOS"
}
actual fun getPlatform(): Platform = OhosPlatform()
internal actual fun getPlatformDemoList(): List<PlatformDemoItem> = listOf(
PlatformDemoItem("interop_list_nested", "混排嵌滑"),
PlatformDemoItem("interop_list_simple", "混排列表"),
PlatformDemoItem("interop_render_order", "混排层级"),
PlatformDemoItem("interop_text_input", "混排输入"),
)
@androidx.compose.runtime.Composable
internal actual fun PlatformDemo(id: String) {
when (id) {
"interop_list_nested" -> InteropListNested()
"interop_list_simple" -> InteropListSimple()
"interop_render_order" -> InteropRenderOrder()
"interop_text_input" -> InteropTextInput()
}
}
package com.dong.demo013
import com.dong.test1.TimerControllerImpl
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import platform.PerformanceAnalysisKit.HiLog.OH_LOG_PrintMsg
actual fun startLog(
speed: Int,
onLogGenerated: ((Int) -> Unit)?,
onTimerUpdated: ((Long) -> Unit)?
): LogController {
val controller = LogControllerImpl()
// 启动协程在后台执行日志生成
GlobalScope.launch {
generateLogs(speed, onLogGenerated, onTimerUpdated, controller)
}
return controller
}
actual fun createTimer(): TimerController {
return TimerControllerImpl()
}
private suspend fun generateLogs(speed: Int, onLogGenerated: ((Int) -> Unit)?, onTimerUpdated: ((Long) -> Unit)?, controller: LogControllerImpl) {
val startTime = getTimeMillis()
var count = 0
// 发送开始日志 (fatal级别)
hiLogPrintMsg(
type = 0u,
level = 4u, // FATAL level
domain = 0x1234u,
tag = "LogGenerator",
message = "日志生成开始,间隔 ${speed} 毫秒,手动停止模式"
)
// 手动停止模式:持续运行直到用户停止
while (controller.isRunning) {
val currentTime = getTimeMillis()
val elapsedSeconds = (currentTime - startTime) / 1000
// 每秒更新一次计时器显示
if (elapsedSeconds > count) {
onTimerUpdated?.invoke(elapsedSeconds)
}
// 发送普通info日志
hiLogPrintMsg(
type = 0u,
level = 1u, // INFO level
domain = 0x1234u,
tag = "LogGenerator",
message = "生成第 ${++count} 条日志,运行时间: $elapsedSeconds 秒"
)
// 通知UI更新计数
onLogGenerated?.invoke(count)
// 等待指定间隔
kotlinx.coroutines.delay(speed.toLong())
}
// 发送结束日志
val finalTime = (getTimeMillis() - startTime) / 1000
hiLogPrintMsg(
type = 0u,
level = 4u, // FATAL level
domain = 0x1234u,
tag = "LogGenerator",
message = "日志生成手动停止,总运行时间: $finalTime 秒,总共生成: $count 条日志"
)
}
// 获取当前时间戳(毫秒)
private fun getTimeMillis(): Long {
return kotlin.time.TimeSource.Monotonic.markNow().elapsedNow().inWholeMilliseconds
}
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
@CName("hiLogPrintMsg")
fun hiLogPrintMsg(type: UInt, level: UInt, domain: UInt, tag: String, message: String): Int {
return try {
OH_LOG_PrintMsg(type, level, domain, tag, message)
} catch (_: Throwable) {
-1
}
}
\ No newline at end of file
package com.dong.test1
import com.dong.demo013.TimerController
import kotlinx.atomicfu.AtomicBoolean
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.delay
class TimerControllerImpl : TimerController {
private val _isRunning = atomic(false)
private val _elapsedTime = atomic(0L)
private var timerJob: Job? = null
private val scope = CoroutineScope(Dispatchers.Default)
override val isRunning: Boolean
get() = _isRunning.value
override val elapsedTime: Long
get() = _elapsedTime.value
override fun start() {
if (!_isRunning.value) {
_isRunning.value = true
startTimer()
}
}
override fun stop() {
if (_isRunning.value) {
_isRunning.value = false
timerJob?.cancel()
}
}
override fun reset() {
stop()
_elapsedTime.value = 0L
}
private fun startTimer() {
timerJob = scope.launch {
while (isRunning) {
delay(1000) // 每秒递增1
_elapsedTime.incrementAndGet()
}
}
}
}
\ No newline at end of file
#Kotlin
kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M
#Gradle
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
org.gradle.configuration-cache=true
org.gradle.caching=true
#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
kotlin.native.cacheKind=none
org.gradle.internal.http.connectionTimeout=100000
org.gradle.internal.http.socketTimeout=100000
[versions]
agp = "8.11.2"
android-compileSdk = "36"
android-minSdk = "24"
android-targetSdk = "36"
androidx-activity = "1.12.2"
androidx-appcompat = "1.7.1"
androidx-constraintlayout = "2.2.1"
androidx-core = "1.17.0"
androidx-espresso = "3.7.0"
androidx-lifecycle = "2.9.6"
androidx-material = "1.12.0"
androidx-testExt = "1.3.0"
androidx-collection = "1.4.5"
compose = "1.9.4"
composeMultiplatform = "1.9.2-ez-001"
junit = "4.13.2"
kotlin = "2.2.21-ez-101"
kotlinx-coroutines = "1.8.0-KBA-001"
atomicFu = "0.23.2-KBA-001"
[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
junit = { module = "junit:junit", version.ref = "junit" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-testExt-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-testExt" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
androidx-collection = { module = "androidx.collection:collection", version.ref = "androidx-collection" }
compose-multiplatform-export = { module = "org.jetbrains.compose.export:export", version.ref = "composeMultiplatform" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" }
androidx-material = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" }
androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
atomicFu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicFu" }
# AndroidX compose, only used by android target.
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
compose-material = { module = "androidx.compose.material:material", version.ref = "compose" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/bin/sh
#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test
/.appanalyzer
{
"app": {
"bundleName": "com.example.harmonyapp",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:layered_image",
"label": "$string:app_name",
"hwasanEnabled": true
}
}
{
"string": [
{
"name": "app_name",
"value": "harmonyApp"
}
]
}
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
}
}
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "/Users/dongsq/.ohos/config/default_harmonyApp_ZL1pLwQsJiEgvxVmw7qyWKFb0jNdPIs3ERZWJYDBw7U=.cer",
"keyAlias": "debugKey",
"keyPassword": "0000001BF2A15C3A6EC270C797CCFEC3753A7D36694F00B2B879B2C997469B98413F3C71E2A0F729293F88",
"profile": "/Users/dongsq/.ohos/config/default_harmonyApp_ZL1pLwQsJiEgvxVmw7qyWKFb0jNdPIs3ERZWJYDBw7U=.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "/Users/dongsq/.ohos/config/default_harmonyApp_ZL1pLwQsJiEgvxVmw7qyWKFb0jNdPIs3ERZWJYDBw7U=.p12",
"storePassword": "0000001BAE6533BE8FB0F0E2790DB2693EA0CCE91314DFAB0B8D41F7F3428FB03D4E16D6F3F662B85F496D"
}
}
],
"products": [
{
"name": "default",
"signingConfig": "default",
"targetSdkVersion": "6.0.0(20)",
"compatibleSdkVersion": "6.0.0(20)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"nativeCompiler": "BiSheng",
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}
{
"files": [
"**/*.ets"
],
"ignore": [
"**/src/ohosTest/**/*",
"**/src/test/**/*",
"**/src/mock/**/*",
"**/node_modules/**/*",
"**/oh_modules/**/*",
"**/build/**/*",
"**/.preview/**/*"
],
"ruleSet": [
"plugin:@performance/recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@security/no-unsafe-aes": "error",
"@security/no-unsafe-hash": "error",
"@security/no-unsafe-mac": "warn",
"@security/no-unsafe-dh": "error",
"@security/no-unsafe-dsa": "error",
"@security/no-unsafe-ecdsa": "error",
"@security/no-unsafe-rsa-encrypt": "error",
"@security/no-unsafe-rsa-sign": "error",
"@security/no-unsafe-rsa-key": "error",
"@security/no-unsafe-dsa-key": "error",
"@security/no-unsafe-dh-key": "error",
"@security/no-unsafe-3des": "error"
}
}
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
{
"apiType": "stageMode",
"buildOption": {
"resOptions": {
"copyCodeResource": {
"enable": false
}
},
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "-DOHOS_ENABLE_HWASAN=ON",
"cppFlags": "",
},
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
}
}
},
"nativeLib": {
"debugSymbol": {
"strip": true,
"exclude": []
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
}
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
-enable-property-obfuscation
-enable-toplevel-obfuscation
-enable-filename-obfuscation
-enable-export-obfuscation
{
"meta": {
"stableOrder": true,
"enableUnifiedLockfile": false
},
"lockfileVersion": 3,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"compose@libs/compose.har": "compose@libs/compose.har",
"libcompose_arkui_utils.so@../oh_modules/.ohpm/compose@h5xuwfo6vqe0fkvy6j77dndaihorlv4+5iu+h2krdy8=/oh_modules/compose/src/main/cpp/types/libcompose_arkui_utils": "libcompose_arkui_utils.so@../oh_modules/.ohpm/compose@h5xuwfo6vqe0fkvy6j77dndaihorlv4+5iu+h2krdy8=/oh_modules/compose/src/main/cpp/types/libcompose_arkui_utils",
"libentry.so@src/main/cpp/types/libentry": "libentry.so@src/main/cpp/types/libentry",
"libskikobridge.so@../oh_modules/.ohpm/skikobridge@y2fnhawohlg+q+eadhgpdonzjxt7nzphn6xzlfx6ile=/oh_modules/skikobridge/src/main/cpp/types/libskikobridge": "libskikobridge.so@../oh_modules/.ohpm/skikobridge@y2fnhawohlg+q+eadhgpdonzjxt7nzphn6xzlfx6ile=/oh_modules/skikobridge/src/main/cpp/types/libskikobridge",
"skikobridge@libs/skikobridge.har": "skikobridge@libs/skikobridge.har"
},
"packages": {
"compose@libs/compose.har": {
"name": "compose",
"version": "1.0.0",
"resolved": "libs/compose.har",
"registryType": "local",
"dependencies": {
"libcompose_arkui_utils.so": "file:./src/main/cpp/types/libcompose_arkui_utils"
}
},
"libcompose_arkui_utils.so@../oh_modules/.ohpm/compose@h5xuwfo6vqe0fkvy6j77dndaihorlv4+5iu+h2krdy8=/oh_modules/compose/src/main/cpp/types/libcompose_arkui_utils": {
"name": "libcompose_arkui_utils.so",
"version": "1.0.0",
"resolved": "../oh_modules/.ohpm/compose@h5xuwfo6vqe0fkvy6j77dndaihorlv4+5iu+h2krdy8=/oh_modules/compose/src/main/cpp/types/libcompose_arkui_utils",
"registryType": "local"
},
"libentry.so@src/main/cpp/types/libentry": {
"name": "libentry.so",
"version": "1.0.0",
"resolved": "src/main/cpp/types/libentry",
"registryType": "local"
},
"libskikobridge.so@../oh_modules/.ohpm/skikobridge@y2fnhawohlg+q+eadhgpdonzjxt7nzphn6xzlfx6ile=/oh_modules/skikobridge/src/main/cpp/types/libskikobridge": {
"name": "libskikobridge.so",
"version": "0.0.0",
"resolved": "../oh_modules/.ohpm/skikobridge@y2fnhawohlg+q+eadhgpdonzjxt7nzphn6xzlfx6ile=/oh_modules/skikobridge/src/main/cpp/types/libskikobridge",
"registryType": "local"
},
"skikobridge@libs/skikobridge.har": {
"name": "skikobridge",
"version": "1.0.0",
"resolved": "libs/skikobridge.har",
"registryType": "local",
"dependencies": {
"libskikobridge.so": "file:./src/main/cpp/types/libskikobridge"
}
}
}
}
\ No newline at end of file
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"libentry.so": "file:./src/main/cpp/types/libentry",
// 添加 compose.har 依赖
"compose": "file:./libs/compose.har",
// 添加 skikobridge.har 依赖
"skikobridge": "file:./libs/skikobridge.har"
}
}
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.5.0)
project(harmonyApp)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
if(DEFINED PACKAGE_FIND_FILE)
include(${PACKAGE_FIND_FILE})
endif()
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
find_package(skikobridge)
add_library(entry SHARED napi_init.cpp)
# Link against ComposeApp shared library to resolve exported symbols
add_library(ComposeApp SHARED IMPORTED)
target_link_libraries(entry PUBLIC libace_napi.z.so)
target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
target_link_libraries(entry PUBLIC libdeviceinfo_ndk.z.so)
target_link_libraries(entry PUBLIC librawfile.z.so)
#target_link_libraries(entry PUBLIC libicu.so)
target_link_libraries(entry PUBLIC skikobridge::skikobridge)
set_target_properties(ComposeApp PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/arm64-v8a/libkn.so"
)
target_link_libraries(entry PUBLIC ComposeApp)
target_link_libraries(entry PUBLIC ${EGL-lib} ${GLES-lib} ${hilog-lib} ${libace-lib} ${libnapi-lib} ${libuv-lib} libc++_shared.so)
#ifndef KONAN_LIBKN_H
#define KONAN_LIBKN_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
typedef bool libkn_KBoolean;
#else
typedef _Bool libkn_KBoolean;
#endif
typedef unsigned short libkn_KChar;
typedef signed char libkn_KByte;
typedef short libkn_KShort;
typedef int libkn_KInt;
typedef long long libkn_KLong;
typedef unsigned char libkn_KUByte;
typedef unsigned short libkn_KUShort;
typedef unsigned int libkn_KUInt;
typedef unsigned long long libkn_KULong;
typedef float libkn_KFloat;
typedef double libkn_KDouble;
typedef float __attribute__ ((__vector_size__ (16))) libkn_KVector128;
typedef void* libkn_KNativePtr;
struct libkn_KType;
typedef struct libkn_KType libkn_KType;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Byte;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Short;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Int;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Long;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Float;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Double;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Char;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Boolean;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Unit;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_UByte;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_UShort;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_UInt;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_ULong;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_Platform;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_TimerController;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Function1;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_LogController;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_collections_List;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_collections_Map;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup_Ui;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup_Foundation;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup_Material;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup_Benchmark;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComposeGroup_Platform;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_ComponentDemo;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_kotlin_Any;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_Page;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_Page_Home;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_navigation_Page_Detail;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_Greeting;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_LogControllerImpl;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_demo013_OhosPlatform;
typedef struct {
libkn_KNativePtr pinned;
} libkn_kref_com_dong_test1_TimerControllerImpl;
extern void* MainArkUIViewController(void* env);
extern libkn_KInt hiLogPrintMsg(libkn_KUInt type, libkn_KUInt level, libkn_KUInt domain, const char* tag, const char* message);
extern void androidx_compose_ui_arkui_ArkUIViewController_aboutToAppear(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_aboutToDisappear(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_cancelSyncRefresh(void* controllerRef, libkn_KInt refreshId);
extern void androidx_compose_ui_arkui_ArkUIViewController_dispatchHoverEvent(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_dispatchMouseEvent(void* controllerRef);
extern libkn_KBoolean androidx_compose_ui_arkui_ArkUIViewController_dispatchTouchEvent(void* controllerRef, void* nativeTouchEvent, libkn_KBoolean ignoreInteropView);
extern const char* androidx_compose_ui_arkui_ArkUIViewController_getId(void* controllerRef);
extern void* androidx_compose_ui_arkui_ArkUIViewController_getXComponentRender(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_keyboardWillHide(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_keyboardWillShow(void* controllerRef, libkn_KFloat keyboardHeight);
extern libkn_KBoolean androidx_compose_ui_arkui_ArkUIViewController_onBackPress(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onFinalize(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onFocusEvent(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onFrame(void* controllerRef, libkn_KLong timestamp, libkn_KLong targetTimestamp);
extern void androidx_compose_ui_arkui_ArkUIViewController_onKeyEvent(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onPageHide(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onPageShow(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onSurfaceChanged(void* controllerRef, libkn_KInt width, libkn_KInt height);
extern void androidx_compose_ui_arkui_ArkUIViewController_onSurfaceCreated(void* controllerRef, void* xcomponentPtr, libkn_KInt width, libkn_KInt height);
extern void androidx_compose_ui_arkui_ArkUIViewController_onSurfaceDestroyed(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onSurfaceHide(void* controllerRef);
extern void androidx_compose_ui_arkui_ArkUIViewController_onSurfaceShow(void* controllerRef);
extern libkn_KInt androidx_compose_ui_arkui_ArkUIViewController_requestSyncRefresh(void* controllerRef);
extern const char* androidx_compose_ui_arkui_ArkUIViewController_sendMessage(void* controllerRef, const char* type, const char* message);
extern void androidx_compose_ui_arkui_ArkUIViewController_setContext(void* controllerRef, void* context);
extern void androidx_compose_ui_arkui_ArkUIViewController_setEnv(void* controllerRef, void* env);
extern void androidx_compose_ui_arkui_ArkUIViewController_setId(void* controllerRef, const char* id);
extern void androidx_compose_ui_arkui_ArkUIViewController_setMessenger(void* controllerRef, void* messenger);
extern void androidx_compose_ui_arkui_ArkUIViewController_setRootView(void* controllerRef, void* backRootView, void* foreRootView, void* touchableRootView);
extern void androidx_compose_ui_arkui_ArkUIViewController_setUIContext(void* controllerRef, void* uiContext);
extern void androidx_compose_ui_arkui_ArkUIViewController_setXComponentRender(void* controllerRef, void* render);
extern void androidx_compose_ui_arkui_init(void* env, void* exports);
typedef struct {
/* Service functions. */
void (*DisposeStablePointer)(libkn_KNativePtr ptr);
void (*DisposeString)(const char* string);
libkn_KBoolean (*IsInstance)(libkn_KNativePtr ref, const libkn_KType* type);
libkn_kref_kotlin_Byte (*createNullableByte)(libkn_KByte);
libkn_KByte (*getNonNullValueOfByte)(libkn_kref_kotlin_Byte);
libkn_kref_kotlin_Short (*createNullableShort)(libkn_KShort);
libkn_KShort (*getNonNullValueOfShort)(libkn_kref_kotlin_Short);
libkn_kref_kotlin_Int (*createNullableInt)(libkn_KInt);
libkn_KInt (*getNonNullValueOfInt)(libkn_kref_kotlin_Int);
libkn_kref_kotlin_Long (*createNullableLong)(libkn_KLong);
libkn_KLong (*getNonNullValueOfLong)(libkn_kref_kotlin_Long);
libkn_kref_kotlin_Float (*createNullableFloat)(libkn_KFloat);
libkn_KFloat (*getNonNullValueOfFloat)(libkn_kref_kotlin_Float);
libkn_kref_kotlin_Double (*createNullableDouble)(libkn_KDouble);
libkn_KDouble (*getNonNullValueOfDouble)(libkn_kref_kotlin_Double);
libkn_kref_kotlin_Char (*createNullableChar)(libkn_KChar);
libkn_KChar (*getNonNullValueOfChar)(libkn_kref_kotlin_Char);
libkn_kref_kotlin_Boolean (*createNullableBoolean)(libkn_KBoolean);
libkn_KBoolean (*getNonNullValueOfBoolean)(libkn_kref_kotlin_Boolean);
libkn_kref_kotlin_Unit (*createNullableUnit)(void);
libkn_kref_kotlin_UByte (*createNullableUByte)(libkn_KUByte);
libkn_KUByte (*getNonNullValueOfUByte)(libkn_kref_kotlin_UByte);
libkn_kref_kotlin_UShort (*createNullableUShort)(libkn_KUShort);
libkn_KUShort (*getNonNullValueOfUShort)(libkn_kref_kotlin_UShort);
libkn_kref_kotlin_UInt (*createNullableUInt)(libkn_KUInt);
libkn_KUInt (*getNonNullValueOfUInt)(libkn_kref_kotlin_UInt);
libkn_kref_kotlin_ULong (*createNullableULong)(libkn_KULong);
libkn_KULong (*getNonNullValueOfULong)(libkn_kref_kotlin_ULong);
/* User functions. */
struct {
struct {
struct {
struct {
struct {
struct {
struct {
struct {
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get)(); /* enum entry for Ui. */
} Ui;
struct {
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get)(); /* enum entry for Foundation. */
} Foundation;
struct {
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get)(); /* enum entry for Material. */
} Material;
struct {
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get)(); /* enum entry for Benchmark. */
} Benchmark;
struct {
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get)(); /* enum entry for Platform. */
} Platform;
libkn_KType* (*_type)(void);
} ComposeGroup;
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_navigation_ComponentDemo (*ComponentDemo)(const char* id, const char* title, libkn_kref_com_dong_demo013_navigation_ComposeGroup group);
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*get_group)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
const char* (*get_id)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
const char* (*get_title)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
const char* (*component1)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
const char* (*component2)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
libkn_kref_com_dong_demo013_navigation_ComposeGroup (*component3)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
libkn_kref_com_dong_demo013_navigation_ComponentDemo (*copy)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz, const char* id, const char* title, libkn_kref_com_dong_demo013_navigation_ComposeGroup group);
libkn_KBoolean (*equals)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz, libkn_kref_kotlin_Any other);
libkn_KInt (*hashCode)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
const char* (*toString)(libkn_kref_com_dong_demo013_navigation_ComponentDemo thiz);
} ComponentDemo;
struct {
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_navigation_Page_Home (*_instance)();
libkn_KBoolean (*equals)(libkn_kref_com_dong_demo013_navigation_Page_Home thiz, libkn_kref_kotlin_Any other);
libkn_KInt (*hashCode)(libkn_kref_com_dong_demo013_navigation_Page_Home thiz);
const char* (*toString)(libkn_kref_com_dong_demo013_navigation_Page_Home thiz);
} Home;
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_navigation_Page_Detail (*Detail)(libkn_kref_com_dong_demo013_navigation_ComponentDemo demo);
libkn_kref_com_dong_demo013_navigation_ComponentDemo (*get_demo)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz);
libkn_kref_com_dong_demo013_navigation_ComponentDemo (*component1)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz);
libkn_kref_com_dong_demo013_navigation_Page_Detail (*copy)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz, libkn_kref_com_dong_demo013_navigation_ComponentDemo demo);
libkn_KBoolean (*equals)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz, libkn_kref_kotlin_Any other);
libkn_KInt (*hashCode)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz);
const char* (*toString)(libkn_kref_com_dong_demo013_navigation_Page_Detail thiz);
} Detail;
libkn_KType* (*_type)(void);
} Page;
libkn_kref_kotlin_collections_List (*get_componentDemos)();
libkn_kref_kotlin_collections_Map (*get_groupTitles)();
libkn_KInt (*com_dong_demo013_navigation_ComponentDemo$stableprop_getter)();
libkn_KInt (*com_dong_demo013_navigation_Page_Detail$stableprop_getter)();
libkn_KInt (*com_dong_demo013_navigation_Page_Home$stableprop_getter)();
libkn_kref_kotlin_collections_Map (*demosByGroup)();
const char* (*demosJson)();
const char* (*groupTitlesJson)();
} navigation;
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_Greeting (*Greeting)();
const char* (*greet)(libkn_kref_com_dong_demo013_Greeting thiz);
} Greeting;
struct {
libkn_KType* (*_type)(void);
libkn_KBoolean (*get_isRunning)(libkn_kref_com_dong_demo013_LogController thiz);
void (*stop)(libkn_kref_com_dong_demo013_LogController thiz);
} LogController;
struct {
libkn_KType* (*_type)(void);
const char* (*get_name)(libkn_kref_com_dong_demo013_Platform thiz);
} Platform;
struct {
libkn_KType* (*_type)(void);
libkn_KLong (*get_elapsedTime)(libkn_kref_com_dong_demo013_TimerController thiz);
libkn_KBoolean (*get_isRunning)(libkn_kref_com_dong_demo013_TimerController thiz);
void (*reset)(libkn_kref_com_dong_demo013_TimerController thiz);
void (*start)(libkn_kref_com_dong_demo013_TimerController thiz);
void (*stop)(libkn_kref_com_dong_demo013_TimerController thiz);
} TimerController;
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_LogControllerImpl (*LogControllerImpl)();
libkn_KBoolean (*get_isRunning)(libkn_kref_com_dong_demo013_LogControllerImpl thiz);
void (*stop)(libkn_kref_com_dong_demo013_LogControllerImpl thiz);
} LogControllerImpl;
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_demo013_OhosPlatform (*OhosPlatform)();
const char* (*get_name)(libkn_kref_com_dong_demo013_OhosPlatform thiz);
} OhosPlatform;
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter_)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter_)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter_)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter__)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter__)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter__)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter___)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter___)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter___)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter____)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter____)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter____)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter_____)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter_____)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter_____)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter______)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter______)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter______)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter_______)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter_______)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter_______)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter________)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter_________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter_________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter_________)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter__________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter__________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter__________)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter___________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter___________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter___________)();
void* (*MainArkUIViewController_)(void* env);
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter____________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter____________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter____________)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter_____________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter_____________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter_____________)();
libkn_kref_com_dong_demo013_Platform (*getPlatform)();
libkn_KInt (*com_dong_demo013_Greeting$stableprop_getter______________)();
libkn_KInt (*com_dong_demo013_LogControllerImpl$stableprop_getter______________)();
libkn_KInt (*com_dong_demo013_OhosPlatform$stableprop_getter______________)();
libkn_kref_com_dong_demo013_TimerController (*createTimer)();
libkn_KInt (*hiLogPrintMsg_)(libkn_KUInt type, libkn_KUInt level, libkn_KUInt domain, const char* tag, const char* message);
libkn_kref_com_dong_demo013_LogController (*startLog)(libkn_KInt speed, libkn_kref_kotlin_Function1 onLogGenerated, libkn_kref_kotlin_Function1 onTimerUpdated);
} demo013;
struct {
struct {
libkn_KType* (*_type)(void);
libkn_kref_com_dong_test1_TimerControllerImpl (*TimerControllerImpl)();
libkn_KLong (*get_elapsedTime)(libkn_kref_com_dong_test1_TimerControllerImpl thiz);
libkn_KBoolean (*get_isRunning)(libkn_kref_com_dong_test1_TimerControllerImpl thiz);
void (*reset)(libkn_kref_com_dong_test1_TimerControllerImpl thiz);
void (*start)(libkn_kref_com_dong_test1_TimerControllerImpl thiz);
void (*stop)(libkn_kref_com_dong_test1_TimerControllerImpl thiz);
} TimerControllerImpl;
libkn_KInt (*com_dong_test1_TimerControllerImpl$stableprop_getter)();
} test1;
} dong;
} com;
struct {
struct {
struct {
struct {
struct {
void (*_Export_ArkUIViewController_aboutToAppear)(void* controllerRef);
void (*_Export_ArkUIViewController_aboutToDisappear)(void* controllerRef);
void (*_Export_ArkUIViewController_cancelSyncRefresh)(void* controllerRef, libkn_KInt refreshId);
void (*_Export_ArkUIViewController_dispatchHoverEvent)(void* controllerRef);
void (*_Export_ArkUIViewController_dispatchMouseEvent)(void* controllerRef);
libkn_KBoolean (*_Export_ArkUIViewController_dispatchTouchEvent)(void* controllerRef, void* nativeTouchEvent, libkn_KBoolean ignoreInteropView);
const char* (*_Export_ArkUIViewController_getId)(void* controllerRef);
void* (*_Export_ArkUIViewController_getXComponentRender)(void* controllerRef);
void (*_Export_ArkUIViewController_keyboardWillHide)(void* controllerRef);
void (*_Export_ArkUIViewController_keyboardWillShow)(void* controllerRef, libkn_KFloat keyboardHeight);
libkn_KBoolean (*_Export_ArkUIViewController_onBackPress)(void* controllerRef);
void (*_Export_ArkUIViewController_onFinalize)(void* controllerRef);
void (*_Export_ArkUIViewController_onFocusEvent)(void* controllerRef);
void (*_Export_ArkUIViewController_onFrame)(void* controllerRef, libkn_KLong timestamp, libkn_KLong targetTimestamp);
void (*_Export_ArkUIViewController_onKeyEvent)(void* controllerRef);
void (*_Export_ArkUIViewController_onPageHide)(void* controllerRef);
void (*_Export_ArkUIViewController_onPageShow)(void* controllerRef);
void (*_Export_ArkUIViewController_onSurfaceChanged)(void* controllerRef, libkn_KInt width, libkn_KInt height);
void (*_Export_ArkUIViewController_onSurfaceCreated)(void* controllerRef, void* xcomponentPtr, libkn_KInt width, libkn_KInt height);
void (*_Export_ArkUIViewController_onSurfaceDestroyed)(void* controllerRef);
void (*_Export_ArkUIViewController_onSurfaceHide)(void* controllerRef);
void (*_Export_ArkUIViewController_onSurfaceShow)(void* controllerRef);
libkn_KInt (*_Export_ArkUIViewController_requestSyncRefresh)(void* controllerRef);
const char* (*_Export_ArkUIViewController_sendMessage)(void* controllerRef, const char* type, const char* message);
void (*_Export_ArkUIViewController_setContext)(void* controllerRef, void* context);
void (*_Export_ArkUIViewController_setEnv)(void* controllerRef, void* env);
void (*_Export_ArkUIViewController_setId)(void* controllerRef, const char* id);
void (*_Export_ArkUIViewController_setMessenger)(void* controllerRef, void* messenger);
void (*_Export_ArkUIViewController_setRootView)(void* controllerRef, void* backRootView, void* foreRootView, void* touchableRootView);
void (*_Export_ArkUIViewController_setUIContext)(void* controllerRef, void* uiContext);
void (*_Export_ArkUIViewController_setXComponentRender)(void* controllerRef, void* render);
void (*_Export_ArkUIViewInitializer_init)(void* env, void* exports);
} arkui;
} ui;
} export_;
} compose;
} androidx;
struct {
struct {
struct {
struct {
libkn_KInt (*demo_composeapp_generated_resources_Res_array$stableprop_getter)();
libkn_KInt (*demo_composeapp_generated_resources_Res_drawable$stableprop_getter)();
libkn_KInt (*demo_composeapp_generated_resources_Res_font$stableprop_getter)();
libkn_KInt (*demo_composeapp_generated_resources_Res_plurals$stableprop_getter)();
libkn_KInt (*demo_composeapp_generated_resources_Res_string$stableprop_getter)();
libkn_KInt (*demo_composeapp_generated_resources_Res_array$stableprop_getter_)();
libkn_KInt (*demo_composeapp_generated_resources_Res_drawable$stableprop_getter_)();
libkn_KInt (*demo_composeapp_generated_resources_Res_font$stableprop_getter_)();
libkn_KInt (*demo_composeapp_generated_resources_Res_plurals$stableprop_getter_)();
libkn_KInt (*demo_composeapp_generated_resources_Res_string$stableprop_getter_)();
libkn_KInt (*demo_composeapp_generated_resources_Res_array$stableprop_getter__)();
libkn_KInt (*demo_composeapp_generated_resources_Res_drawable$stableprop_getter__)();
libkn_KInt (*demo_composeapp_generated_resources_Res_font$stableprop_getter__)();
libkn_KInt (*demo_composeapp_generated_resources_Res_plurals$stableprop_getter__)();
libkn_KInt (*demo_composeapp_generated_resources_Res_string$stableprop_getter__)();
libkn_KInt (*demo_composeapp_generated_resources_Res_array$stableprop_getter___)();
libkn_KInt (*demo_composeapp_generated_resources_Res_drawable$stableprop_getter___)();
libkn_KInt (*demo_composeapp_generated_resources_Res_font$stableprop_getter___)();
libkn_KInt (*demo_composeapp_generated_resources_Res_plurals$stableprop_getter___)();
libkn_KInt (*demo_composeapp_generated_resources_Res_string$stableprop_getter___)();
} resources;
} generated;
} composeapp;
} demo;
} root;
} kotlin;
} libkn_ExportedSymbols;
extern libkn_ExportedSymbols* libkn_symbols(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* KONAN_LIBKN_H */
#include "libkn_api.h"
#include "napi/native_api.h"
#include <rawfile/raw_file_manager.h>
#include <dlfcn.h>
static napi_value MainArkUIViewController(napi_env env, napi_callback_info info) {
return reinterpret_cast<napi_value>(MainArkUIViewController(env));
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
androidx_compose_ui_arkui_init(env, exports);
napi_property_descriptor desc[] = {
{"MainArkUIViewController", nullptr, MainArkUIViewController, nullptr, nullptr, nullptr, napi_default, nullptr},
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{
napi_module_register(&demoModule);
}
import { ArkUIViewController } from "compose/src/main/cpp/types/libcompose_arkui_utils";
export const MainArkUIViewController: () => ArkUIViewController
{
"name": "libentry.so",
"types": "./Index.d.ts",
"version": "1.0.0",
"description": "Please describe the basic information."
}
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}
}
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
const DOMAIN = 0x0000;
export default class EntryBackupAbility extends BackupExtensionAbility {
async onBackup() {
hilog.info(DOMAIN, 'testTag', 'onBackup ok');
await Promise.resolve();
}
async onRestore(bundleVersion: BundleVersion) {
hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
await Promise.resolve();
}
}
import { promptAction } from '@kit.ArkUI';
interface ButtonArgs {
text: string
backgroundColor: string
}
@Builder
export function buttonBuilder(args: ButtonArgs) {
button()
}
@Component
export struct button {
@Consume compose_args: ButtonArgs
build() {
Column() {
Button(this.compose_args.text).backgroundColor(this.compose_args.backgroundColor).width('100%').onClick(e => {
console.log(`Button Clicked: ${this.compose_args.text}`)
}).height('70%')
Stack().height('10%')
}
}
}
interface TextArgs {
id: string
text: string
backgroundColor: string
}
@Builder
export function textBuilder(args: TextArgs) {
text()
}
@Component
export struct text {
@Consume compose_args: TextArgs
build() {
Text(this.compose_args.id + " " + this.compose_args.text)
.backgroundColor(this.compose_args.backgroundColor)
.width('100%')
.height('100%')
.borderRadius('5vp')
.onClick(e => {
console.log(`Text Clicked: ${JSON.stringify(this.compose_args)}`)
})
}
}
@Builder
export function labelBuilder(args: ButtonArgs) {
label()
}
@Component
export struct label {
@Consume compose_args: ButtonArgs
build() {
Column() {
Button(`+ ${this.compose_args.text}`, { type: ButtonType.Normal })
.backgroundColor(this.compose_args.backgroundColor)
.width('100%')
.height('50%')
.borderRadius(2)
.onClick(e => {
promptAction.showToast({
message: this.compose_args.text
})
})
Text(this.compose_args.text).backgroundColor(Color.Orange).width('100%').height('50%')
}
}
}
@Builder
export function layerBuilder(args: ButtonArgs) {
layer()
}
@Component
export struct layer {
@Consume compose_args: ButtonArgs
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
Text(this.compose_args.text)
}
.width('100%')
.height('100%')
.backgroundColor(this.compose_args.backgroundColor)
.onClick(() => {
promptAction.showToast({ message: `${this.compose_args.text} Clicked` })
})
.onTouch(e => {
console.log(`layer ${this.compose_args.text} onTouch`)
})
}
}
@Builder
export function buttonWrapContentBuilder(args: ButtonArgs) {
buttonWrapContent()
}
@Component
export struct buttonWrapContent {
@Consume compose_args: ButtonArgs
build() {
Column() {
Button(this.compose_args.text).backgroundColor(this.compose_args.backgroundColor).width('100%').onClick(e => {
console.log(`Button Clicked: ${this.compose_args.text}`)
})
Text(this.compose_args.text).backgroundColor(this.compose_args.backgroundColor).width('100%').onClick(e => {
console.log(`Text Clicked: ${this.compose_args.text}`)
})
}
}
}
interface InputArgs {
text: string
}
@Builder
export function textInputBuilder(args: InputArgs) {
textInput()
}
@Component
export struct textInput {
@Consume compose_args: InputArgs
build() {
Column() {
TextInput({ text: $$this.compose_args.text }).onChange(value => {
console.log(`/// onChange: ${value}`)
})
Text("ArkUI组件更新:").fontColor(Color.Gray).margin({ top: 30 })
Text(this.compose_args.text)
.width('100%')
.padding(10)
.border({ width: 1, color: Color.Gray })
}.alignItems(HorizontalAlign.Start)
}
}
@Builder
export function verticalListBuilder(args?: object) {
verticalList()
}
@Component
export struct verticalList {
build() {
Row() {
List() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number, index) => {
ListItem() {
Button({ type: ButtonType.Normal }) {
Text(`Ark Button ${index}`)
.fontSize(16)
.fontColor(Color.White)
}
.borderRadius(2)
.height('100vp')
.padding(10)
}.padding(10)
})
}.listDirection(Axis.Vertical).height('100%').width('40%')
Stack().width('20%').height('100%').borderWidth(1)
Scroll() {
Column() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number, index) => {
ListItem() {
Button({ type: ButtonType.Normal }) {
Text(`Ark Button ${index}`).fontSize(16).fontColor(Color.White)
}
.borderRadius(2).height('100vp').padding(10)
}.padding(10)
})
}
}.scrollable(ScrollDirection.Vertical).height('100%').width('40%')
}
}
}
@Builder
export function horizontalListBuilder(args?: object) {
horizontalList()
}
@Component
export struct horizontalList {
build() {
Column() {
List() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number, index) => {
ListItem() {
Button({ type: ButtonType.Normal }) {
Text(`Ark Button ${index}`).fontSize(16).fontColor(Color.White)
}
.borderRadius(2).height('100vp')
}.padding(10)
})
}.listDirection(Axis.Horizontal).height('40%').width('100%')
Stack().width('100%').height('20%').borderWidth(1)
Scroll() {
Row() {
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number, index) => {
ListItem() {
Button({ type: ButtonType.Normal }) {
Text(`Ark Button ${index}`).fontSize(16).fontColor(Color.White)
}
.borderRadius(2).height('100vp')
}.padding(10)
})
}
}.scrollable(ScrollDirection.Horizontal).height('40%').width('100%')
}
}
}
import { registerComposeInteropBuilder } from 'compose/src/main/ets/compose/ArkUIView';
import {
buttonBuilder,
textBuilder,
labelBuilder,
textInputBuilder,
buttonWrapContentBuilder,
layerBuilder,
verticalListBuilder,
horizontalListBuilder,
} from './ComposeInterops';
export function registerComposeInteropBuilders() {
registerComposeInteropBuilder('button', buttonBuilder)
registerComposeInteropBuilder('label', labelBuilder)
registerComposeInteropBuilder('buttonWrapContent', buttonWrapContentBuilder)
registerComposeInteropBuilder('textInput', textInputBuilder)
registerComposeInteropBuilder('layer', layerBuilder)
registerComposeInteropBuilder('text', textBuilder)
registerComposeInteropBuilder('verticalList', verticalListBuilder)
registerComposeInteropBuilder('horizontalList', horizontalListBuilder)
}
import { ArkUIViewController, Compose } from 'compose';
import { hilog } from '@kit.PerformanceAnalysisKit';
import nativeApi from 'libentry.so';
import { registerComposeInteropBuilders } from './ComposeSample';
registerComposeInteropBuilders();
const DOMAIN = 0x0000;
@Entry
@Component
struct Index {
private controller: ArkUIViewController | undefined = undefined;
@State errorMessage: string = 'Native module not ready';
aboutToAppear() {
if (nativeApi === undefined) {
hilog.error(DOMAIN, 'Compose', 'nativeApi is undefined, cannot create controller');
this.errorMessage = 'nativeApi is undefined';
return;
}
try {
this.controller = nativeApi.MainArkUIViewController();
const state = this.controller ? 'created' : 'not_created';
hilog.info(DOMAIN, 'Compose', 'controller init state: %{public}s', state);
if (!this.controller) {
this.errorMessage = 'Controller creation failed (returned null)';
}
} catch (e) {
hilog.error(DOMAIN, 'Compose', 'Exception creating controller: %{public}s', JSON.stringify(e));
this.errorMessage = 'Exception creating controller: ' + JSON.stringify(e);
}
}
build() {
Column() {
if (this.controller) {
Compose({
controller: this.controller,
libraryName: 'entry',
onBackPressed: () => this.controller!.onBackPress()
})
} else {
Text(this.errorMessage)
}
}
.width('100%')
.height('100%')
}
onPageHide() {
if (this.controller) {
this.controller.onPageHide();
}
}
onBackPressed(): boolean {
return this.controller ? this.controller.onBackPress() : false;
}
}
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"orientation": "auto_rotation",
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
]
}
],
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
}
]
}
}
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}
{
"float": [
{
"name": "page_text_font_size",
"value": "50fp"
}
]
}
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}
\ No newline at end of file
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
}
}
{
"color": [
{
"name": "start_window_background",
"value": "#000000"
}
]
}
const NativeMock: Record<string, Object> = {
'add': (a: number, b: number) => {
return a + b;
},
};
export default NativeMock;
{
"libentry.so": {
"source": "src/mock/Libentry.mock.ets"
}
}
import { hilog } from '@kit.PerformanceAnalysisKit';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}
{
"module": {
"name": "entry_test",
"type": "feature",
"deviceTypes": [
"phone"
],
"deliveryWithInstall": true,
"installationFree": false
}
}
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}
{
"modelVersion": "6.0.0",
"dependencies": {
},
"execution": {
// "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | "ultrafine" | false ]. Default: "normal" */
// "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
// "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
// "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
// "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
// "optimizationStrategy": "memory" /* Define the optimization strategy. Value: [ "memory" | "performance" ]. Default: "memory" */
},
"logging": {
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
},
"debugging": {
// "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
},
"nodeOptions": {
// "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
// "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
}
}
import { appTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
}
{
"meta": {
"stableOrder": true,
"enableUnifiedLockfile": false
},
"lockfileVersion": 3,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0",
"@ohos/hypium@1.0.24": "@ohos/hypium@1.0.24"
},
"packages": {
"@ohos/hamock@1.0.0": {
"name": "@ohos/hamock",
"version": "1.0.0",
"integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==",
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har",
"registryType": "ohpm"
},
"@ohos/hypium@1.0.24": {
"name": "@ohos/hypium",
"version": "1.0.24",
"integrity": "sha512-3dCqc+BAR5LqEGG2Vtzi8O3r7ci/3fYU+FWjwvUobbfko7DUnXGOccaror0yYuUhJfXzFK0aZNMGSnXaTwEnbw==",
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.24.har",
"registryType": "ohpm"
}
}
}
\ No newline at end of file
{
"modelVersion": "6.0.0",
"description": "Please describe the basic information.",
"dependencies": {
},
"devDependencies": {
"@ohos/hypium": "1.0.24",
"@ohos/hamock": "1.0.0"
}
}
TEAM_ID=
PRODUCT_NAME=Demo
PRODUCT_BUNDLE_IDENTIFIER=com.dong.demo013.Demo$(TEAM_ID)
CURRENT_PROJECT_VERSION=1
MARKETING_VERSION=1.0
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };
058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };
7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = "<group>"; };
7555FF7B242A565900829871 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B92378962B6B1156000C7307 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
058557D7273AAEEB004C7B11 /* Preview Content */ = {
isa = PBXGroup;
children = (
058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
42799AB246E5F90AF97AA0EF /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
7555FF72242A565900829871 = {
isa = PBXGroup;
children = (
AB1DB47929225F7C00F7AF9C /* Configuration */,
7555FF7D242A565900829871 /* iosApp */,
7555FF7C242A565900829871 /* Products */,
42799AB246E5F90AF97AA0EF /* Frameworks */,
);
sourceTree = "<group>";
};
7555FF7C242A565900829871 /* Products */ = {
isa = PBXGroup;
children = (
7555FF7B242A565900829871 /* Demo.app */,
);
name = Products;
sourceTree = "<group>";
};
7555FF7D242A565900829871 /* iosApp */ = {
isa = PBXGroup;
children = (
058557BA273AAA24004C7B11 /* Assets.xcassets */,
7555FF82242A565900829871 /* ContentView.swift */,
7555FF8C242A565B00829871 /* Info.plist */,
2152FB032600AC8F00CF470E /* iOSApp.swift */,
058557D7273AAEEB004C7B11 /* Preview Content */,
);
path = iosApp;
sourceTree = "<group>";
};
AB1DB47929225F7C00F7AF9C /* Configuration */ = {
isa = PBXGroup;
children = (
AB3632DC29227652001CCB65 /* Config.xcconfig */,
);
path = Configuration;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7555FF7A242A565900829871 /* iosApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */;
buildPhases = (
F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */,
7555FF77242A565900829871 /* Sources */,
B92378962B6B1156000C7307 /* Frameworks */,
7555FF79242A565900829871 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = iosApp;
packageProductDependencies = (
);
productName = iosApp;
productReference = 7555FF7B242A565900829871 /* Demo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7555FF73242A565900829871 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 1540;
ORGANIZATIONNAME = orgName;
TargetAttributes = {
7555FF7A242A565900829871 = {
CreatedOnToolsVersion = 11.3.1;
};
};
};
buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7555FF72242A565900829871;
packageReferences = (
);
productRefGroup = 7555FF7C242A565900829871 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7555FF7A242A565900829871 /* iosApp */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7555FF79242A565900829871 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */,
058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Compile Kotlin Framework";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7555FF77242A565900829871 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,
7555FF83242A565900829871 /* ContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
7555FFA3242A565B00829871 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
7555FFA4242A565B00829871 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
7555FFA6242A565B00829871 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
DEVELOPMENT_TEAM = "${TEAM_ID}";
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
);
INFOPLIST_FILE = iosApp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-framework",
composeApp,
);
PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
PRODUCT_NAME = "Demo";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
7555FFA7242A565B00829871 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
DEVELOPMENT_TEAM = "${TEAM_ID}";
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
);
INFOPLIST_FILE = iosApp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-framework",
composeApp,
);
PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
PRODUCT_NAME = "Demo";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7555FFA3242A565B00829871 /* Debug */,
7555FFA4242A565B00829871 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7555FFA6242A565B00829871 /* Debug */,
7555FFA7242A565B00829871 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7555FF73242A565900829871 /* Project object */;
}
\ No newline at end of file
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
\ No newline at end of file
{
"images": [
{
"idiom": "universal",
"platform": "ios",
"size": "1024x1024"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
\ No newline at end of file
{
"info": {
"author": "xcode",
"version": 1
}
}
\ No newline at end of file
import UIKit
import SwiftUI
import ComposeApp
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.keyboard) // Compose has own keyboard handler
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
{
"info": {
"author": "xcode",
"version": 1
}
}
\ No newline at end of file
import ComposeApp
import SwiftUI
@main
struct iOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
\ No newline at end of file
rootProject.name = "Demo"
// 启用类型安全项目访问器特性(Type-safe project accessors)
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
/**
专门管理 Gradle 插件的解析和应用:
影响 plugins {} 块中的插件解析
影响 buildscript {} 块中的插件解析
影响插件版本管理
影响插件仓库配置
只在构建脚本配置阶段生效
*/
pluginManagement {
repositories {
maven("https://maven.eazytec-cloud.com/nexus/repository/maven-public/")
// 引入 Gradle 插件门户(主要用于查找 Gradle 插件)
gradlePluginPortal()
}
}
/**
专门管理项目依赖的解析:
影响 dependencies {} 块中的依赖解析
影响 implementation、api、compileOnly 等依赖声明
影响依赖版本管理
影响依赖仓库配置
在整个项目构建过程中生效
*/
dependencyResolutionManagement {
repositories {
maven("https://maven.eazytec-cloud.com/nexus/repository/maven-public/")
}
}
// 包含 composeApp 模块
include(":composeApp")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment