近来鸿蒙是比较火的, 正好这几天也在调研鸿蒙系统,今天解包鸿蒙Java和JS 的输出物,比较下他们的区别。
1 基本概念
鸿蒙输出物有2种,一种是hap格式, 另外一种是app, 简单来说,后者是前者的集合;
引用官方的一张图:
这里选择hap进行解析, 由于鸿蒙可以使用多语言开发, 这里选择应用开发流行度最广的 Java 和 JavaScript 进行解析。
2 Android apk 结构
这里先简单说一下Android APK 的结构, 以便于对比。
对于安卓开发者来说这个结构不会陌生,下面简单描述下重要的文件:
*.dex: 咱们编写的或项目引用三方库的代码编译后的产物res: 资源目录,里面放着layout,drawable,anim等文件META-INF: 一些描述文件,以及V1签名相关文件kotlin:kotlin语言类和方法的一些描述信息,暂时忽略,目前鸿蒙还不支持kotlin开发;resources.arsc: 资源索引;
接下来看下Java编写鸿蒙app的结构
3 hap结构:Java
主要分为以下内容:
-
assets: 资源目录
- entry/resources: 资源文件
- entry/resources.index: 资源索引文件
-
class.dex: java代码编译输出物,跟安卓的一样
-
config.json & pack.json: 类似于安卓的清单文件; 贴下他们的内容
// config.json
{
"app": {
"apiVersion": {
"compatible": 4,
"releaseType": "Release",
"target": 5
},
"vendor": "example",
"bundleName": "com.example.hydemo",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"abilities": [{
"iconId": 16777219,
"skills": [{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}],
"orientation": "unspecified",
"descriptionId": 16777218,
"labelId": 16777216,
"icon": "$media:icon",
"name": "com.example.hydemo.MainAbility",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"homeAbility": true,
"launchType": "standard"
}],
"deviceType": ["phone"],
"mainAbility": "com.example.hydemo.MainAbility",
"distro": {
"moduleType": "entry",
"installationFree": false,
"deliveryWithInstall": true,
"moduleName": "entry"
},
"package": "com.example.hydemo",
"name": ".MyApplication"
}
}
//pack.json
{
"summary": {
"app": {
"bundleName": "com.example.hydemo",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"modules": [
{
"mainAbility": "com.example.hydemo.MainAbility",
"deviceType": [
"phone"
],
"abilities": [
{
"name": "com.example.hydemo.MainAbility",
"label": "$string:entry_MainAbility"
}
],
"distro": {
"moduleType": "entry",
"installationFree": false,
"deliveryWithInstall": true,
"moduleName": "entry"
},
"apiVersion": {
"compatible": 4,
"releaseType": "Release",
"target": 5
}
}
]
},
"packages": [
{
"deviceType": [
"phone"
],
"moduleType": "entry",
"deliveryWithInstall": true,
"name": "entry-debug-rich-unsigned"
}
]
}
大家光看名字估计就能猜出很多配置的意思, 这里就不多说了
- entry_debug_signed_entry.apk: 这个就很有意思了,意味有点深远; 一会咱们逆向看下里面的内容。
可以看出总体和安卓的apk文件还是十分相似的, 下面进行逆向:
3.1 dex文件内容
不看类内容我还以为打开了一个安卓的dex文件;
咱们来逐一打开看看内容:
就一个字,像,跟安卓几乎一模一样;
和安卓的R文件极其相似
集成了AbilityPackage, 这个应该是鸿蒙sdk提供的,这里看不到源码;顺便说一句,这个类在DevEco Studio里也没有源码;
MainAbility像一个入口,MainAbilitySlice和安卓的Activity就很像了;
3.2 entry_debug_signed_entry.apk 内容
打开后发现,只有3个类,还有一个是R文件,忽略掉R文件看下ShellMyApplication和MainAbilityShellActivity内容:
没什么内容,基本上都是父类实现的,咱们去DevEco Studio中找下这他们的父类:
看类的声明发现: 前者继承了安卓的Application,后者继承了安卓的Activity;
这种作法感觉像是为了安卓兼容鸿蒙准备的,如果有大神知道的话,希望能够告知,非常感谢!
到这里, 基本上 hap 的内容和结构大家都清楚了, 整体上来说和安卓apk极其相似,内部居然还包含了一个apk文件, 我第一次看到的时候有种看到彩蛋的感觉;
4 hap结构:JavaScript
直接上图:
和java开发的包不同的地方在于 assets 目录下多了 js 文件, 也就是说你写的js代码全部被打包在这个目录下;我简单看了下,应该是通过webpack打包;
这个结构让我想起来了快应用和小程序,并且感觉这部分代码应该天然支持热更新和插件化;难倒最终还是JavaScript 一统天下么=.=
我对JavaScript 了解不深,所以这块就不多说了; 有兴趣的同学可以自己解包一个看看,还是挺有意思的;
5 结束
以上就是今天的全部内容, 主要是带大家简单看下鸿蒙输出物和安卓输出物的结构,最后再来张图