鸿蒙混合打包(支持安卓、鸿蒙相互调用) 原创 精华

没用的喵叔
发布于 2021-6-28 19:56
浏览
22收藏

最新消息:此方案打出的包已$\color{#ff0000}{不能上架}$,请大家知悉

签名相关的问题,就不要在下面问了!
如果遇到问题,建议重复阅读2.1、5.1、5.3、5.4!
如果还有问题,也欢迎勇跃提问!

高效提问的最基础前提就是先排除自身的问题。


先放代码:
-----> 喵叔catuncle / 鸿蒙混合打包 <-----

介绍

鸿蒙混合打包。在现有安卓应用的基础上扩展鸿蒙的特性,以最快的速度布局鸿蒙生态!

参考:京东APP鸿蒙版上架实践本项目只是这篇文章的一个验证,让更多的兄弟们可以少走弯路。

我尽可能把每一步的改动作为一个commit,这样方便大家看代码。

开发步骤

  1. 准备Android工程

    本示例中,我用AS建了一个Hello World工程。

  2. Android工程改造

    请参考京东APP鸿蒙版上架实践

    这一步,有两点要注意的:

    1. abilityshell_ide_java.jar在鸿蒙sdk目录(---->你自己电脑里!<----) ,自行copy到安卓工程中 鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区
    2. 注意apk文件名必须是 xxx-entry.apk这种格式
  3. 准备鸿蒙工程

    本示例中,我用DevEco Studio建了一个Hello World工程。 鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区

  4. 配置鸿蒙工程

    请参考京东APP鸿蒙版上架实践

    这一步,有三点要注意的:

    1. 签名就不要转了,直接重新创建,只要秘钥和别名和Android的保持不变。(如果在模拟器上运行,不配置签名也能跑起来)

    2. 鸿蒙的version 和apk的version要一致

    3. config.json的app节点下,增加relatedBundleName而不是originalName

      config.json里都支持哪些字段,没必要看文档,只要按住ctrl点击相应的字段,就可以看到,比如点击app字段。 鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区

  5. 卡片

    本示例中,我用DevEco Studio建了一个名为mycard的module ,并且勾选"show in service center",这样这个卡片就可以显示在"服务中心"了。鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区

    有几点需要说明:

    1. 必须签名(我的验证结果是这样的),所以要有真机。我提交的签名文件是绑定我的机器,所以你要更新自己的签名文件。
    2. 卡片的config.json的app字段要和entry的app字段完全一致relatedBundleName字段只在entry里有就可以,卡片里不写也行)
    3. 多module的工程,运行的时候要勾选Deploy Multi Hap Packages鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区
    4. 为什么把卡片放在独立的module里?因为混合打包下,entry只是一个壳,我们可以把entry当作apk的占位,所以entry里的内容都不会打到app里,鸿蒙相关的功能代码我们只能放在独立的module中。(当然,这也是我的验证结果,最终要等华为官方更明确的文档解释)
  6. 鸿蒙打开apk中的activity

    请参考京东APP鸿蒙版上架实践

  7. 鸿蒙打开apk中的activity,并传递参数

    • 鸿蒙IntentParams对应安卓Bundle,相应的api
      //ohos put:
      IntentParams params = new IntentParams();
      params.setParam("androidFile1","androidFile1----");
      intent.setParams(params);
      
      //android put:
      Intent intent = new Intent();
      intent.putExtra("androidFile1","androidFile1----");
      
      //get:
      intent.getStringExtra("androidFile1");
      //ohos put:
      Set<String> entities = new HashSet<>();
      entities.add("entity.user.c1");
      
    • 鸿蒙Uri对应安卓Uri,鸿蒙Entity对应安卓Category,相应的api
      //ohos put:
      Operation operation = new Intent.OperationBuilder()
              .withUri(Uri.parse("https://www.baidu.com"))
              .withEntities(entities)
              .build();
      
      //android put:
      Intent intent = new Intent();
      intent.setData(Uri.parse("https://www.baidu.com"));
      intent.addCategory("entity.user.c1");
      
      //get:
      intent.getData();
      intent.getCategories();
      
  8. 安卓打开鸿蒙中的ability,并传递参数

    • 核心代码:

      Intent intent = new Intent();
      //CardAbility有对应的代理类CardAbilityShellActivity,我们可以这样理解。
      ComponentName componentName = new ComponentName("wang.unclecat.hello","wang.unclecat.mycard.CardAbilityShellActivity");
      intent.putExtra("msg","鸿蒙哥哥,我是安卓");
      intent.setComponent(componentName);
      startActivity(intent);
      
    • 原理:鸿蒙工程在编译期,Ability会生成相应的代理类XXXShellActivity。如下图所示。我们只要访问这个代理Activity,就可以在apk中访问相应的Ability了。

      以上都只是猜测,试过之后,还真的可行。

      鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区
      鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区

    最终效果

    鸿蒙混合打包(支持安卓、鸿蒙相互调用)-鸿蒙开发者社区

常见问题(欢迎评论区补充)

  • Failure[INSTALL_FAILED_INCONSISTENT_BUNDLE_VERSION]
    混合打合时要和apk 的version一致
  • Failure[INSTALL_FAILED_RESTRICTED_PERMISSIONS_NOT_GRANTED]
    没有继承HarmonyApplication或者没有配置到AndroidManifest.xml中
  • Failure[INSTALL_FAILED_INTERNAL_ERROR]
    确认一下:
    在AndroidManifest.xml中,向根节点下增加。
     <uses-feature android:name="zidane.software.ability" android:required="false" />
    
    向application节点下新增子节点。
      <meta-data android:name="permZA" android:value="true" />
      <meta-data android:name="multiFrameworkBundle" android:value="true" />
    

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2021-8-13 15:30:42修改
21
收藏 22
回复
举报
49条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

楼主先行排雷,感谢分享。

回复
2021-6-29 09:49:37
凡尘一梦
凡尘一梦

INSTALL_FAILED_INTERNAL_ERROR

harmony要求程序必须是64位的,这个错误也有可能是app中打入了32位的so

 

2
回复
2021-6-29 10:56:40
没用的喵叔
没用的喵叔 回复了 凡尘一梦
INSTALL_FAILED_INTERNAL_ERROR harmony要求程序必须是64位的,这个错误也有可能是app中打入了32位的so

准确讲,如果有so文件,必须有arm64-v8a。当然也可以有armeabi和armeabi-v7a,只不过在鸿蒙的手机上不会用到。为了减小包的体积,适配鸿蒙的apk一般只有arm64-v8a。

回复
2021-6-29 12:43:29
guo754687222
guo754687222

INSTALL_FAILED_RESTRICTED_PERMISSIONS_NOT_GRANTED 我之前遇到这个错,原因是因为apk里加了读取手机联系人的权限,去掉就好了。

回复
2021-6-30 15:25:19
没用的喵叔
没用的喵叔 回复了 guo754687222
INSTALL_FAILED_RESTRICTED_PERMISSIONS_NOT_GRANTED 我之前遇到这个错,原因是因为apk里加了读取手机联系人的权限,去掉就好了。

如果不去掉,有什么解决办法呢?

回复
2021-6-30 18:26:52
qq60c8715b6c08b
qq60c8715b6c08b

Failed to load signer "signer #1"
java.io.IOException: Keystore was tampered with, or password was incorrect

加了module之后点运行就提示签名有问题,debug签名是自动的,release签名我也配置了,不知道是什么情况,请教下

回复
2021-7-1 11:11:25
guo754687222
guo754687222 回复了 没用的喵叔
如果不去掉,有什么解决办法呢?

目前我没想到别的办法,我在鸿蒙里申请了权限也不行。所以目前只好去掉了

回复
2021-7-1 11:26:35
无妻徒刑一百年
无妻徒刑一百年 回复了 qq60c8715b6c08b
Failed to load signer "signer #1"java.io.IOException: Keystore was tampered with, or password was incorrect 加了module之后点运行就提示签名有问题,debug签名是自动的,release签名我也配置了,不知道是什么情况,请教下

module的build里也要配置签名,可以直接把entry的复制过去,然后启动entry的时候要勾选deployMultiHapPackages

回复
2021-7-1 11:29:07
qq60c8715b6c08b
qq60c8715b6c08b 回复了 无妻徒刑一百年
module的build里也要配置签名,可以直接把entry的复制过去,然后启动entry的时候要勾选deployMultiHapPackages

 

我都填的了,debug,release都已经配置,都是这样的情况

已于2021-7-1 14:31:03修改
回复
2021-7-1 11:37:51
guo754687222
guo754687222 回复了 guo754687222
目前我没想到别的办法,我在鸿蒙里申请了权限也不行。所以目前只好去掉了

我发现注册应用时,可以申请这2个权限,我觉得申请后就可以了,但是我没试。

回复
2021-7-1 20:06:25
qq60c077669a284
qq60c077669a284 回复了 qq60c8715b6c08b
Failed to load signer "signer #1"java.io.IOException: Keystore was tampered with, or password was incorrect 加了module之后点运行就提示签名有问题,debug签名是自动的,release签名我也配置了,不知道是什么情况,请教下

我创建完卡片module之后,也是你这种问题,是签名配置错了。

解决:保证Android项目和鸿蒙项目签名信息一致的前提下,准备好这几个文件。p12是和签名文件csr一块生成的(这个应该没问题);cer是证书,在华为后台-用户与访问-证书管理-新增证书,提交后下载;p7b也是在后台下载,在项目-应用页面-右上角添加,提交后下载。

这样回到项目中配置debug签名信息就行了,不要用自动生成的。

 

回复
2021-7-2 18:23:59
生活追寻
生活追寻

直接用你的工程代码下载下来运行,报Activity class {wang.unclecat.hello/wang.unclecat.hello.MainAbilityShellActivity} does not exist.

3
回复
2021-7-3 10:46:55
没用的喵叔
没用的喵叔 回复了 生活追寻
直接用你的工程代码下载下来运行,报Activity class {wang.unclecat.hello/wang.unclecat.hello.MainAbilityShellActivity} does not exist.

卡片的功能正常吗?我怀疑你没有把mycard那个module打进去。我有提到注意事项。

回复
2021-7-3 11:03:15
生活追寻
生活追寻 回复了 没用的喵叔
卡片的功能正常吗?我怀疑你没有把mycard那个module打进去。我有提到注意事项。

我只是entry 选择了Deploy mutilple Hap packages,我把mycard 没勾选,加上,可以了!

回复
2021-7-3 12:09:28
Fluency.L
Fluency.L

非常感谢这篇文章,问个问题,现有AndroidAPP(已经在华为应用商店上架)如果想要改造,不改变包名的前提下可以吗?如果不改变包名,那么App gallery上创建鸿蒙应用填写包名时会提示现有包名已存在。

回复
2021-7-5 15:55:46
没用的喵叔
没用的喵叔 回复了 爱吃橘子的牛
抱歉,此内容已被作者删除

我怀疑你根本没看文章。

回复
2021-7-5 17:54:11
没用的喵叔
没用的喵叔 回复了 Fluency.L
非常感谢这篇文章,问个问题,现有AndroidAPP(已经在华为应用商店上架)如果想要改造,不改变包名的前提下可以吗?如果不改变包名,那么App gallery上创建鸿蒙应用填写包名时会提示现有包名已存在。

这个问题,你联系华为官方吧。现在已知的是京东、优酷视频的app改造是没有改变包名。

回复
2021-7-5 17:57:16
wx60e2f86ca961d
wx60e2f86ca961d

INSTALL_FAILED_APP_SOURCE_NOT_TRUSTED  报了这个错误呢

回复
2021-7-5 20:18:23
没用的喵叔
没用的喵叔 回复了 生活追寻
直接用你的工程代码下载下来运行,报Activity class {wang.unclecat.hello/wang.unclecat.hello.MainAbilityShellActivity} does not exist.

MainAbility不会打进最终的包里。看5.4,我有提到

回复
2021-7-6 02:58:12
揭开了红帽子
揭开了红帽子

感谢楼主分享,已经成功,但有个问题,就是在card module中修改超级卡片相关创建、刷新方法时好像不起作用,同样的代码在纯鸿蒙项目中是work的,请问楼主有遇到这个问题吗?会是什么问题呢?

回复
2021-7-6 11:52:27
回复