首先我们来看一下官方的 Changelog 这个版本有哪些 breaking changes。其中大部分变更暂时我还没有使用到,所以就忽略。但是 Android 有个变更貌似改变挺大了,也直接导致了大部分的第三方插件直接无法使用

1
2
3
Change the application template (49f20f4) - @foghina
* Plugins which pass activity reference in the constructor need to be updated to extend ReactContextBaseJavaModule use getCurrentActivity to get the activity reference. This change is backward compatible.
* Apps need to be migrated to use the latest template

大概的意思是:这个版本我们变更了 APP 的模板,如果你的插件选择在构造函数中传递当前的 activity,那么在这个版本中需要升级到通过继承 ReactContextBaseJavaModule 来获取当前的 activity,这个改变是可以向下兼容的。

部分第三方插件无法使用了

其中我正在使用的 react-native-extra-dimensions-android 也是遇到了相同的问题,而且好像作者好像弃坑了,所以只能自己尝试按照上面官方的建议进行改造升级

1
2
error: incompatible types <anonymous ReactNativeHost> cannot be converted to Ativity
new ExtraDimensionsPackage(this) <--

尝试改造第三方插件

自己动手,丰衣足食。下面的步骤是针对 react-native-extra-dimensions-android 进行改造,但是整个改造的过程是适合其他遇到相同问题的插件,万变不离其宗。

在 MainApplication.java 注册插件

从 v0.29.0 开始,Android 项目新增了 MainApplication.java 模板,大部分以前在 MainActivity.java 的逻辑迁移到了这里

Register module (in MainApplication.java)

1
2
3
4
5
6
7
8
9
10
11
12
import ca.jaysoo.extradimensions.ExtraDimensionsPackage; // <--- import
public class MainApplication extends Application implements ReactApplication {
......
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ExtraDimensionsPackage() // <--- add here
);
}
......
}

上面只是代码位置迁移,只是 new 的时候少了 this 这个参数,因为这时候 this 已经不再是 current activity 了,这也是导致整个问题的重要原因!

尝试通过其他方法找回 Current Activity

因为 Current Activity 已经不再通过构造函数传递进来了,我们只能通过其他的方式尝试找回 Current Activity

ExtraDimensionsPackage 类中已经没有 activity 相关的逻辑了,那我们清理一下无用的代码。

image

接下来就是重点了,修改 ExtraDimensionsModule 类中相关的代码。按照官方的建议通过继承 ReactContextBaseJavaModule 来获取 getCurrentActivity() 这个方法,看起来好容易就可以完成啦!!

image

继承、重写生命周期的部分方法…上面其实都是例行书写,对于改造是没有任何卵用的。
接下来按道理我们只用全局替换 mCurrentActivitygetCurrentActivity() 就可以大功告成了。

编译、运行…哎呀,我艹,没有 getCurrentActivity() 这个方法?不是官方推荐的吗?方法呢?被狗吃了吗?
后来我尝试去翻源码,60%确定这个方法不存在或者没有暴露出来,但是毕竟我只是个小前端,可能用错了吧。

(16.08.16更新)在 RN0.31.0 中 getCurrentActivity() 被 public 出来了,基本上我上面说的是对的,这个方法被狗吃了。具体的 commit 可以参阅:7606564

先不管了,那就查查还有什么方法可以获取到 Current Activity,Google 告诉我 WindowManager 也是可以拿到当前活跃的 activity 的!

image

大功告成!!