HighCapable / YukiHookAPI

⛱️ An efficient Hook API and Xposed Module solution built in Kotlin.
https://highcapable.github.io/YukiHookAPI/
Apache License 2.0
1.42k stars 105 forks source link

模块无法收到从宿主传来的消息 #68

Closed cledwynl closed 7 months ago

cledwynl commented 7 months ago

项目地址 https://github.com/cledwynl/mbga/tree/34c32c470ba26153242064f5ba765eddf9611de3

模块的流程是这样的:

  1. 打开宿主
  2. 在宿主内点击某个区域打开模块的Activity
  3. 模块向宿主发送请求
  4. 宿主收到后向模块发送数据,这一步模块没收到

初步排查下来发现是模块的BroadcastReceiver在收到广播后调用的YukiHookDataChannel.isCurrentBroadcast中获取不到task

image

接着我尝试将模块Activity加上了

<intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

再试就成功收到消息了。有没有什么方式可以让不展示在启动器的Activity接收消息

fankes commented 7 months ago

不用呀,你测试的 Android 版本是什么,我需要知道

cledwynl commented 7 months ago

安卓13和安卓12

fankes commented 7 months ago

在你需要接收广播的 Activity 配置中只需要添加 android:exported="true" 就可以了,你试试。

cledwynl commented 7 months ago

似乎不行,能确定Activity是android:exported="true"的。而且显示在启动器之后,也需要先从启动器打开模块后才能收到消息。如果先把模块杀后台,再从宿主内跳转到模块Activity,也收不到消息。

我在demo上复现了一下,把intent-filter注释掉了,然后在点击SEND MSG TO MODULE时跳转模块,延迟3秒再发送消息,结果模块没收到消息。

https://github.com/cledwynl/YukiHookAPI/commit/a3292aa999d56da2d1eca23d2a7047db2c150d32

BTW, 我的测试设备是

fankes commented 7 months ago

不可以的,模块和宿主必须保持存活

fankes commented 7 months ago

你可以参考 https://github.com/fankes/MIUINativeNotifyIcon 这个项目,这个就是使用二级页面发送的消息

fankes commented 7 months ago

你可以描述一下你的使用场景,一般情况下不建议直接做广播通信

cledwynl commented 7 months ago

你可以描述一下你的使用场景,一般情况下不建议直接做广播通信

我的模块设置界面需要动态展示一些选项(屏蔽底部导航栏的tab),所以需要从宿主那边查询一些信息(导航栏有哪些tab)。所以现在我打算这样做,因为模块设置界面只能从宿主跳转来,所以我认为进入设置界面时宿主一定存活,然后设置界面会向宿主发一条消息,宿主收到消息以后把tab信息发送给设置界面,设置界面再根据信息展示选项。

不可以的,模块和宿主必须保持存活

不太确定你说的存活是否和我理解的相同,我目前的场景下宿主给模块发消息时,模块的设置界面是在前台运行的(虽然这个设置界面是宿主startActivity打开的),我理解这个状态也是“存活”

fankes commented 7 months ago

你可以通过非 Activity 发送和接收广播,比如 getApplication(),这样就可以绕过判断是否为当前 Activity 接收广播的限制

cledwynl commented 7 months ago

成功了!感谢解答

activity?.dataChannel()改成activity?.application?.dataChannel()就能接收到宿主传来的消息了

fankes commented 7 months ago

成功了!感谢解答

activity?.dataChannel() 改成 activity?.application?.dataChannel() 就能接收到宿主传来的消息了

这个限制是我手动加的,因为会考虑到当前多个 Activity 注册了广播监听的情况,这样在你发送广播的时候,可能已经打开了二级页面,但是之前的页面还是能重复收到广播,所以判断了是否为当前 Activity,如果你没有这个需求,就可以使用 Application 注册全局广播,就不会受到 Activtity 的作用域限制。