Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ Compose 源码
}
```

接下来在DevEco Studio中构建鸿蒙应用,安装到真机/模拟器运行。也可以在 composeApp 中执行 `startHarmonyAppDebug` 或 `startHarmonyAppRelease` gradle任务,完成整个kotlin项目构建,复制产物,鸿蒙项目构建,发送真机/模拟器运行流程。

### 在Compose中使用ArkUI

ovCompose可与ArkUI框架混排。您可以将 Compose Multiplatform 嵌入到 ArkUI 应用中,也可以将原生 ArkUI
Expand Down
114 changes: 114 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,117 @@ arrayOf("debug", "release").forEach { type ->
}
}
}

arrayOf("debug", "release").forEach { type ->

tasks.register<Copy>("startHarmonyApp${type.capitalizeUS()}") {
group = "harmony"
dependsOn("link${type.capitalizeUS()}SharedOhosArm64")

// Disable configuration cache for this task
notCompatibleWithConfigurationCache("Uses project.exec and file() at execution time")

// Move problematic property evaluations to doLast to avoid configuration cache issues
val harmonyAppDir: String by project
val absoluteHarmonyAppDir = if (File(harmonyAppDir).isAbsolute) harmonyAppDir else
rootProject.file(harmonyAppDir).absolutePath

into(rootProject.file(absoluteHarmonyAppDir))
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/")
}

outputs.upToDateWhen { false }
doLast {
val appJsonContent = file("$absoluteHarmonyAppDir/AppScope/app.json5").readText()
val bundleNameRegex = """"bundleName"\s*:\s*"([^"]+)"""".toRegex()
val bundleName = bundleNameRegex.find(appJsonContent)?.groupValues?.get(1) ?: error("bundleName not found")
val devEcoStudioDir: String by project
val harmonyAppEntryModuleDir: String by project
val hFileDir: String by project
val soFileDir: String by project
val abilityName: String by project
val nodeHome = "$devEcoStudioDir/Contents/tools/node"
val devEcoSdkHome = "$devEcoStudioDir/Contents/sdk"

if (!File(devEcoStudioDir).exists()) {
throw GradleException("Provided DevEco Studio install path doesn't exist: $devEcoStudioDir")
}
fun execAtHarmonyAppDir(cmd: List<String>) {
val result = project.exec {
environment(mapOf("NODE_HOME" to nodeHome, "DEVECO_SDK_HOME" to devEcoSdkHome))
commandLine(cmd)
workingDir(absoluteHarmonyAppDir)
isIgnoreExitValue = true
}
if (result.exitValue != 0) {
throw GradleException("${cmd.joinToString(" ")}\nFailed with exit code ${result.exitValue}\nTry to reproduce this in DevEco Studio's command line, otherwise you would need to setup some enviroment parameters")
}
}

println("=== Step 1: Install OHPM dependencies ===")
execAtHarmonyAppDir(listOf(
"$devEcoStudioDir/Contents/tools/ohpm/bin/ohpm",
"install",
"--all",
"--registry",
"https://ohpm.openharmony.cn/ohpm/",
"--strict_ssl",
"true"
))

println("=== Step 2: Run hvigor sync ===")
execAtHarmonyAppDir(listOf(
"$devEcoStudioDir/Contents/tools/node/bin/node",
"$devEcoStudioDir/Contents/tools/hvigor/bin/hvigorw.js",
"--sync",
"-p", "product=default",
"-p", "buildMode=${type}",
"--analyze=false",
"--parallel",
"--incremental",
"--daemon"
))

println("=== Step 3: Build HAP ===")
execAtHarmonyAppDir(listOf(
"$devEcoStudioDir/Contents/tools/node/bin/node",
"$devEcoStudioDir/Contents/tools/hvigor/bin/hvigorw.js",
"--mode", "module",
"-p", "module=entry@default",
"-p", "product=default",
"-p", "buildMode=${type}",
"-p", "requiredDeviceType=phone",
"assembleHap",
"--analyze=false",
"--parallel",
"--incremental",
"--daemon"
))

println("=== Step 4: Install HAP to device via hdc ===")
val hapFolder = File("$absoluteHarmonyAppDir/$harmonyAppEntryModuleDir/build/default/outputs/default/")
val hapFile = File(hapFolder, "entry-default-signed.hap").takeIf { it.exists() } ?: File(hapFolder, "entry-default-unsigned.hap")

execAtHarmonyAppDir(listOf(
"$devEcoStudioDir/Contents/sdk/default/openharmony/toolchains/hdc",
"install",
hapFile.absolutePath
))

println("=== Step 5: Launch app on device ===")
println("Ability: $abilityName, Bundle: $bundleName")
execAtHarmonyAppDir(listOf(
"$devEcoStudioDir/Contents/sdk/default/openharmony/toolchains/hdc",
"shell",
"aa",
"start",
"-a", abilityName,
"-b", bundleName
))
}
}
}
16 changes: 15 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,18 @@ org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8

#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
android.useAndroidX=true

# Settings for startHarmonyApp gradle task
# DevEco Studio install path
devEcoStudioDir=/Applications/DevEco-Studio.app
# harmony project root folder, absolute path or relative to this project root
harmonyAppDir=harmonyApp
# Folder name of entry module in harmony app
harmonyAppEntryModuleDir=entry/
# Where header artifact of kotlin project should go
hFileDir=src/main/cpp/include/
# Where so artifact of kotlin project should go
soFileDir=libs/arm64-v8a/
# The ability to start, click run in DevEco Studio, this comes after 'hdc shell aa start -a' in run log
abilityName = EntryAbility
1 change: 1 addition & 0 deletions harmonyApp/entry/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/libs/arm64-v8a/
/node_modules
/oh_modules
/.preview
Expand Down
Binary file removed harmonyApp/entry/libs/arm64-v8a/libkn.so
Binary file not shown.