Commit 129844ac authored by dsq's avatar dsq

添加原生页面

parent cd0cb983
......@@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript">
function configurationCacheProblems() { return (
// begin-report-data
{"diagnostics":[{"locations":[{"pluginId":"org.jetbrains.kotlin.multiplatform"}],"problem":[{"text":"Default Kotlin Hierarchy Template Not Applied Correctly"}],"severity":"WARNING","problemDetails":[{"text":"The Default Kotlin Hierarchy Template was not applied to 'project ':shared'':\nExplicit .dependsOn() edges were configured for the following source sets:\n[ohosArm64Main, ohosX64Main]\n\nConsider removing dependsOn-calls or disabling the default template by adding\n 'kotlin.mpp.applyDefaultHierarchyTemplate=false'\nto your gradle.properties"}],"contextualLabel":"Default Kotlin Hierarchy Template Not Applied Correctly","documentationLink":"https://kotl.in/hierarchy-template","problemId":[{"name":"KGP:MISCONFIGURATION","displayName":"Kotlin Gradle Plugin Misconfiguration"},{"name":"KOTLIN","displayName":"Kotlin"},{"name":"KotlinDefaultHierarchyFallbackDependsOnUsageDetected","displayName":"Default Kotlin Hierarchy Template Not Applied Correctly"}],"solutions":[[{"text":"Please remove the dependsOn-calls or disable the default template."}]]},{"locations":[{},{"pluginId":"com.android.internal.library"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/8.14.3/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":2,"buildName":"NoComposeDemo","requestedTasks":":shared:publishReleaseBinariesToHarmonyApp","documentationLink":"https://docs.gradle.org/8.14.3/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
{"diagnostics":[{"locations":[{},{"pluginId":"com.android.internal.library"}],"problem":[{"text":"Declaring an 'is-' property with a Boolean type has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"Starting with Gradle 9.0, this property will be ignored by Gradle."}],"contextualLabel":"Declaring an 'is-' property with a Boolean type has been deprecated.","documentationLink":"https://docs.gradle.org/8.14.3/userguide/upgrading_version_8.html#groovy_boolean_properties","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"declaring-an-is-property-with-a-boolean-type","displayName":"Declaring an 'is-' property with a Boolean type has been deprecated."}],"solutions":[[{"text":"Add a method named 'getCrunchPngs' with the same behavior and mark the old one with @Deprecated, or change the type of 'com.android.build.gradle.internal.dsl.BuildType$AgpDecorated.isCrunchPngs' (and the setter) to 'boolean'."}],[{"text":"The combination of method name and return type is not consistent with Java Bean property rules and will become unsupported in future versions of Groovy."}]]},{"locations":[{},{"pluginId":"com.android.internal.library"}],"problem":[{"text":"Declaring an 'is-' property with a Boolean type has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"Starting with Gradle 9.0, this property will be ignored by Gradle."}],"contextualLabel":"Declaring an 'is-' property with a Boolean type has been deprecated.","documentationLink":"https://docs.gradle.org/8.14.3/userguide/upgrading_version_8.html#groovy_boolean_properties","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"declaring-an-is-property-with-a-boolean-type","displayName":"Declaring an 'is-' property with a Boolean type has been deprecated."}],"solutions":[[{"text":"Add a method named 'getUseProguard' with the same behavior and mark the old one with @Deprecated, or change the type of 'com.android.build.gradle.internal.dsl.BuildType.isUseProguard' (and the setter) to 'boolean'."}],[{"text":"The combination of method name and return type is not consistent with Java Bean property rules and will become unsupported in future versions of Groovy."}]]},{"locations":[{},{"pluginId":"com.android.internal.library"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10.0."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/8.14.3/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":3,"buildName":"NoComposeDemo","requestedTasks":":shared:publishReleaseBinariesToHarmonyApp","documentationLink":"https://docs.gradle.org/8.14.3/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data
);}
</script>
......
......@@ -9,4 +9,6 @@ org.gradle.caching=true
#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
\ No newline at end of file
android.useAndroidX=true
kotlin.mpp.applyDefaultHierarchyTemplate=false
\ No newline at end of file
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "/Users/dongsq/.ohos/config/default_harmonyApp_2W8fuyi6g1qRq9PEULU0L1ihZD6WLc_vaAVe6obCWU0=.cer",
"keyAlias": "debugKey",
"keyPassword": "0000001B21D58F6A296219D01BB329D5D20D2D4AD74CB812DDEBC11DE9B6658D8256DE9C964A4C2E1F2BF9",
"profile": "/Users/dongsq/.ohos/config/default_harmonyApp_2W8fuyi6g1qRq9PEULU0L1ihZD6WLc_vaAVe6obCWU0=.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "/Users/dongsq/.ohos/config/default_harmonyApp_2W8fuyi6g1qRq9PEULU0L1ihZD6WLc_vaAVe6obCWU0=.p12",
"storePassword": "0000001BC2EB6CFDB483693260AAEFC83E6E34D4926D1E586C685795DD11A3B75C5B746C8D202A7ECE9E0E"
}
}
],
"products": [
{
"name": "default",
......
......@@ -131,6 +131,7 @@ typedef struct {
const char* (*get_name)(libkn_kref_com_dong_nocomposedemo_OhosPlatform thiz);
} OhosPlatform;
libkn_kref_com_dong_nocomposedemo_Platform (*getPlatform)();
libkn_KInt (*getSum)(libkn_KInt a, libkn_KInt b);
void (*FaultOut_)();
libkn_KInt (*hiLogPrintMsg_)(libkn_KUInt type, libkn_KUInt level, libkn_KUInt domain, const char* tag, const char* message);
void (*pirntAllLevelHiLog_)();
......
......@@ -67,6 +67,38 @@ static napi_value FaultOut(napi_env env, napi_callback_info info)
return undefined;
}
// getSum 包装函数
static napi_value GetSum(napi_env env, napi_callback_info info)
{
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t value0;
napi_get_value_int32(env, args[0], &value0);
int32_t value1;
napi_get_value_int32(env, args[1], &value1);
napi_value sum;
napi_create_int32(env, libkn_symbols()->kotlin.root.com.dong.nocomposedemo.getSum(value0, value1), &sum);
return sum;
}
// NativeCrash 包装函数 - 触发原生越界崩溃
static napi_value NativeCrash(napi_env env, napi_callback_info info)
{
// 通过空指针访问触发原生崩溃
volatile int* ptr = nullptr;
*ptr = 42; // 段错误
napi_value undefined;
napi_get_undefined(env, &undefined);
return undefined;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
......@@ -75,7 +107,9 @@ static napi_value Init(napi_env env, napi_value exports)
{ "pirntSingleHiLog", nullptr, PirntSingleHiLog, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "pirntAllLevelHiLog", nullptr, PirntAllLevelHiLog, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "pirntRandomHiLog", nullptr, PirntRandomHiLog, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "FaultOut", nullptr, FaultOut, nullptr, nullptr, nullptr, napi_default, nullptr }
{ "FaultOut", nullptr, FaultOut, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "getSum", nullptr, GetSum, nullptr, nullptr, nullptr, napi_default, nullptr },
{ "nativeCrash", nullptr, NativeCrash, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
......
......@@ -4,6 +4,7 @@ export interface testNapi {
pirntAllLevelHiLog: () => void;
pirntRandomHiLog: () => void;
FaultOut: () => void;
getSum: (a: number, b: number) => number;
}
declare const testNapi: testNapi;
......
import testNapi from 'libentry.so';
import router from '@ohos.router';
import { printRandomNativeLog } from './HiLogUtils';
@Entry
@Component
......
import { hilog } from '@kit.PerformanceAnalysisKit';
import router from '@ohos.router';
import { printRandomNativeLog } from './HiLogUtils';
@Entry
@Component
struct ContinuousLogPageNative {
@State message: string = '大量持续日志输出 - 原生实现';
@State isRunning: boolean = false;
@State elapsedTime: number = 0; // 经过的秒数
private logTimer: number = -1; // 日志定时器 ID(100ms)
private displayTimer: number = -1; // 显示定时器 ID(1s)
aboutToAppear() {
// 初始化状态
this.isRunning = false;
this.elapsedTime = 0;
}
aboutToDisappear() {
// 清理定时器
this.stopAllTimers();
}
startContinuousLog() {
if (this.isRunning) {
return;
}
this.isRunning = true;
this.elapsedTime = 0;
// 每 100ms 调用一次 printRandomNativeLog
this.logTimer = setInterval(() => {
printRandomNativeLog();
}, 100);
// 每秒更新一次显示
this.displayTimer = setInterval(() => {
this.elapsedTime++;
}, 1000);
}
stopContinuousLog() {
this.stopAllTimers();
this.isRunning = false;
this.elapsedTime = 0;
}
stopAllTimers() {
if (this.logTimer !== -1) {
clearInterval(this.logTimer);
this.logTimer = -1;
}
if (this.displayTimer !== -1) {
clearInterval(this.displayTimer);
this.displayTimer = -1;
}
}
build() {
Column() {
// 顶部返回栏
Row() {
Button('< 返回')
.fontSize(20)
.fontColor('#007DFF')
.backgroundColor(Color.Transparent)
.onClick(() => {
router.back();
})
Text('大量持续日志输出 - 原生')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
.textAlign(TextAlign.Center)
.margin({ right: 60 })
}
.width('100%')
.padding({ left: 20, right: 20, top: 20, bottom: 10 })
.justifyContent(FlexAlign.Start)
// 说明文字
Text('点击开始后每 100ms 生成一条随机日志(原生实现)')
.fontSize(16)
.fontColor('#666666')
.margin({ bottom: 30 })
// 计时器显示
Text(`已运行:${this.elapsedTime} 秒`)
.fontSize(20)
.fontColor('#007DFF')
.fontWeight(FontWeight.Medium)
.margin({ bottom: 50 })
// 状态显示
Text(this.isRunning ? '正在输出日志...' : '已停止')
.fontSize(18)
.fontColor(this.isRunning ? '#FF4444' : '#666666')
.margin({ bottom: 50 })
// 按钮行
Row() {
// 开始按钮
Button('开始')
.width('40%')
.height(50)
.backgroundColor('#00D900')
.enabled(!this.isRunning)
.onClick(() => {
this.startContinuousLog();
})
// 停止按钮
Button('停止')
.width('40%')
.height(50)
.backgroundColor('#FF4444')
.enabled(this.isRunning)
.onClick(() => {
this.stopContinuousLog();
})
}
.width('80%')
.justifyContent(FlexAlign.SpaceEvenly)
.margin({ top: 20 })
// 返回按钮
Button('返回')
.width('40%')
.margin({ top: 20 })
.height(50)
.backgroundColor('#007DFF')
.onClick(() => {
router.back();
})
}
.width('100%')
.height('100%')
}
}
import router from '@ohos.router';
@Entry
@Component
struct FaultPageNative {
@State message: string = '原生崩溃测试页面';
private obj: Object | null = null;
build() {
Column() {
// 标题
Text('原生崩溃测试')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 50, bottom: 30 })
// 说明文字
Text('点击下方按钮将触发空对象访问崩溃')
.fontSize(16)
.fontColor('#666666')
.margin({ bottom: 50 })
// 触发崩溃按钮
Button('触发原生崩溃')
.width('80%')
.height(50)
.backgroundColor('#FF4444')
.margin({ bottom: 20 })
.onClick(() => {
// 访问 null 对象的属性,触发崩溃
let value: string = (this.obj as Object).toString();
})
// 返回按钮
Button('返回')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.onClick(() => {
router.back();
})
}
.width('100%')
.height('100%')
}
}
import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN = 0x1234;
const TAG = 'TestTag';
/**
* 单次日志打印 - 原生实现
*/
export function printSingleNativeLog(): void {
hilog.info(0x0000, TAG, '单次日志打印 - 原生实现');
}
/**
* 打印所有层级日志 - 原生实现
*/
export function printAllLevelsNativeLog(): void {
hilog.debug(0x0000, TAG, 'DEBUG 级别日志 - 原生实现');
hilog.info(0x0000, TAG, 'INFO 级别日志 - 原生实现');
hilog.warn(0x0000, TAG, 'WARN 级别日志 - 原生实现');
hilog.error(0x0000, TAG, 'ERROR 级别日志 - 原生实现');
hilog.fatal(0x0000, TAG, 'FATAL 级别日志 - 原生实现');
}
/**
* 随机日志打印 - 原生实现
*/
export function printRandomNativeLog(): void {
const levels = ['debug', 'info', 'warn', 'error', 'fatal'];
const randomIndex = Math.floor(Math.random() * levels.length);
const level = levels[randomIndex];
switch (level) {
case 'debug':
hilog.debug(0x0000, TAG, `随机日志:级别=${level} - 原生实现`);
break;
case 'info':
hilog.info(0x0000, TAG, `随机日志:级别=${level} - 原生实现`);
break;
case 'warn':
hilog.warn(0x0000, TAG, `随机日志:级别=${level} - 原生实现`);
break;
case 'error':
hilog.error(0x0000, TAG, `随机日志:级别=${level} - 原生实现`);
break;
case 'fatal':
hilog.fatal(0x0000, TAG, `随机日志:级别=${level} - 原生实现`);
break;
}
}
import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';
import router from '@ohos.router';
import { printSingleNativeLog, printAllLevelsNativeLog, printRandomNativeLog } from './HiLogUtils';
const DOMAIN = 0x0000;
......@@ -8,55 +9,127 @@ const DOMAIN = 0x0000;
@Component
struct Index {
@State message: string = 'Hello World';
@State sumResult: string = '';
@State isNativeMode: boolean = true; // true=原生模式,false=NAPI 模式
build() {
Column() {
// 结果描述文本
Text(this.sumResult)
.id('ResultText')
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.margin({ bottom: 20 })
.visibility(this.sumResult ? Visibility.Visible : Visibility.Hidden)
// 标题
Text('日志测试模块')
.id('LogTitle')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 50, bottom: 30 })
.margin({ top: 20, bottom: 30 })
// 单次日志测试按钮
Button('单次日志测试')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
testNapi.pirntSingleHiLog();
})
// 模式切换开关
Row() {
Text('原生模式')
.fontSize(16)
.fontColor(this.isNativeMode ? '#007DFF' : '#666666')
Toggle({ type: ToggleType.Switch, isOn: this.isNativeMode })
.selectedColor('#007DFF')
.onChange((isOn: boolean) => {
this.isNativeMode = isOn;
})
Text('NAPI 模式')
.fontSize(16)
.fontColor(!this.isNativeMode ? '#007DFF' : '#666666')
}
.width('80%')
.justifyContent(FlexAlign.SpaceBetween)
.margin({ bottom: 30 })
// 一次打印所有层级日志按钮
Button('一次打印所有层级日志')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
testNapi.pirntAllLevelHiLog();
})
// 大量持续日志输出按钮
Button('进入持续日志页面')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/ContinuousLogPage' });
})
// 越界崩溃测试按钮
Button('进入越界页面')
.width('80%')
.height(50)
.backgroundColor('#FF4444')
.onClick(() => {
router.pushUrl({ url: 'pages/FaultPage' });
})
// 单次日志测试按钮 - 原生
if (this.isNativeMode) {
Button('单次日志测试(原生)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
printSingleNativeLog();
})
// 一次打印所有层级日志按钮 - 原生
Button('一次打印所有层级日志(原生)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
printAllLevelsNativeLog();
})
// 大量持续日志输出按钮 - 原生
Button('进入持续日志页面(原生)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/ContinuousLogPageNative' });
})
// 越界崩溃测试按钮 - 原生
Button('进入越界页面(原生)')
.width('80%')
.height(50)
.backgroundColor('#FF4444')
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/FaultPageNative' });
})
} else {
// 单次日志测试按钮 - NAPI
Button('单次日志测试(NAPI)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
testNapi.pirntSingleHiLog();
})
// 一次打印所有层级日志按钮 - NAPI
Button('一次打印所有层级日志(NAPI)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
testNapi.pirntAllLevelHiLog();
})
// 大量持续日志输出按钮 - NAPI
Button('进入持续日志页面(NAPI)')
.width('80%')
.height(50)
.backgroundColor('#007DFF')
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/ContinuousLogPage' });
})
// 越界崩溃测试按钮 - NAPI
Button('进入越界页面(NAPI)')
.width('80%')
.height(50)
.backgroundColor('#FF4444')
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/FaultPage' });
})
}
}
.width('100%')
.height('100%')
......
......@@ -2,6 +2,8 @@
"src": [
"pages/Index",
"pages/FaultPage",
"pages/ContinuousLogPage"
"pages/FaultPageNative",
"pages/ContinuousLogPage",
"pages/ContinuousLogPageNative"
]
}
......@@ -6,4 +6,7 @@ class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
\ No newline at end of file
actual fun getPlatform(): Platform = AndroidPlatform()
actual fun getSum(a: Int, b: Int): Int {
TODO("Not yet implemented")
}
\ No newline at end of file
......@@ -4,4 +4,7 @@ interface Platform {
val name: String
}
expect fun getPlatform(): Platform
\ No newline at end of file
expect fun getPlatform(): Platform
expect fun getSum(a: Int, b: Int):Int;
\ No newline at end of file
package com.dong.nocomposedemo
actual fun getPlatform(): Platform {
TODO("Not yet implemented")
}
actual fun getSum(a: Int, b: Int): Int {
TODO("Not yet implemented")
}
\ No newline at end of file
package com.dong.nocomposedemo
actual fun getPlatform(): Platform {
TODO("Not yet implemented")
}
actual fun getSum(a: Int, b: Int): Int {
TODO("Not yet implemented")
}
\ No newline at end of file
......@@ -5,4 +5,8 @@ class OhosPlatform: Platform {
}
actual fun getPlatform(): Platform {
return OhosPlatform()
}
actual fun getSum(a: Int, b: Int): Int {
return a+b;
}
\ No newline at end of file
......@@ -6,4 +6,8 @@ class OhosPlatform: Platform {
}
actual fun getPlatform(): Platform {
return OhosPlatform()
}
actual fun getSum(a: Int, b: Int): Int {
return a+b;
}
\ No newline at end of file
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