【鸿蒙】app输出物解析

809 阅读3分钟

近来鸿蒙是比较火的, 正好这几天也在调研鸿蒙系统,今天解包鸿蒙Java和JS 的输出物,比较下他们的区别。

1 基本概念

鸿蒙输出物有2种,一种是hap格式, 另外一种是app, 简单来说,后者是前者的集合;
引用官方的一张图:

image.png

这里选择hap进行解析, 由于鸿蒙可以使用多语言开发, 这里选择应用开发流行度最广的 Java 和 JavaScript 进行解析。

2 Android apk 结构

这里先简单说一下Android APK 的结构, 以便于对比。

image.png

对于安卓开发者来说这个结构不会陌生,下面简单描述下重要的文件:

  • *.dex: 咱们编写的或项目引用三方库的代码编译后的产物
  • res: 资源目录,里面放着 layout,drawable,anim 等文件
  • META-INF: 一些描述文件,以及V1签名相关文件
  • kotlinkotlin语言 类和方法的一些描述信息,暂时忽略,目前鸿蒙还不支持kotlin开发;
  • resources.arsc: 资源索引;

接下来看下Java编写鸿蒙app的结构

3 hap结构:Java

image.png

主要分为以下内容:

  • 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文件内容

image.png

不看类内容我还以为打开了一个安卓的dex文件;

咱们来逐一打开看看内容:

image.png

就一个字,像,跟安卓几乎一模一样;

image.png

和安卓的R文件极其相似

image.png

集成了AbilityPackage, 这个应该是鸿蒙sdk提供的,这里看不到源码;顺便说一句,这个类在DevEco Studio里也没有源码;

image.png

image.png

MainAbility像一个入口,MainAbilitySlice和安卓的Activity就很像了;

3.2 entry_debug_signed_entry.apk 内容

image.png

打开后发现,只有3个类,还有一个是R文件,忽略掉R文件看下ShellMyApplicationMainAbilityShellActivity内容:

image.png

image.png

没什么内容,基本上都是父类实现的,咱们去DevEco Studio中找下这他们的父类:

image.png

image.png

看类的声明发现: 前者继承了安卓的Application,后者继承了安卓的Activity;

这种作法感觉像是为了安卓兼容鸿蒙准备的,如果有大神知道的话,希望能够告知,非常感谢!

到这里, 基本上 hap 的内容和结构大家都清楚了, 整体上来说和安卓apk极其相似,内部居然还包含了一个apk文件, 我第一次看到的时候有种看到彩蛋的感觉;

4 hap结构:JavaScript

直接上图:

image.png

java开发的包不同的地方在于 assets 目录下多了 js 文件, 也就是说你写的js代码全部被打包在这个目录下;我简单看了下,应该是通过webpack打包;

这个结构让我想起来了快应用和小程序,并且感觉这部分代码应该天然支持热更新和插件化;难倒最终还是JavaScript 一统天下么=.=

我对JavaScript 了解不深,所以这块就不多说了; 有兴趣的同学可以自己解包一个看看,还是挺有意思的;

5 结束

以上就是今天的全部内容, 主要是带大家简单看下鸿蒙输出物和安卓输出物的结构,最后再来张图

c7db2e2b-6ffe-49ef-8408-bb05851643b7.jpg