Kotlin中使Companion object不被混淆

用Kotlin进行Android开发时,单例模式也是用得比较多的场景。由于Kotlin中没有static关键字,创建类的单例一般会使用Companion objct来进行创建。代码如下:

class BleApi private constructor(){ 
  private object BleApiHolder{
     val instance = BleApi()
  }
  companion object {
     @JvmStatic
     val instance:BleApi
         get() = BleApiHolder.instance
  }
}

在Java中我们可以调用BleApi.getInstance()来获取BleApi单例

在Kotlin中我们可以调用BleApi.instance()来获取BleApi单例

如果代码不进行混淆的话,那么以上使用是不会出问题的,但如果要对代码进行混淆,那么你会发现Kotlin中调用不了instance来获取到BleApi。

我们混淆代码如下

-keep class com.calm.comm.lib.ble.BleApi{
    *;
}

What?不是已经排除了BleApi的类不混淆了么。But,我们是按Java的规则在混淆啊。所以悲剧就产生了,在混淆时混淆器还是会将Companion object进行混淆,由于我们注解了@JvmStatic,这个相当于Java中的static,所以在Java中使用是不会出现问题的。但在Kotlin 中,就呵呵了!

既然找到了原因,那我们就想办法来处理。

打开BleApi类,打开Tools->Kotlin->Show Kotlin Bytecode。我们可以看到Kotlin生成的Bytecode的代码。可以看到生成有个类public final class com/calm/comm/lib/ble/BleApi$Companion,原来Kotlin的Companion object会生成这个类,那么我们可以-keep掉这个类不被混淆就可以解决这个问题了。

So,在混淆代码加入如下语句:

-keep class com.calm.comm.lib.ble.BleApi$Companion{
    *;
}

然后在用Kotlin测试调用BleApi.instance()就没有问题了。

你可能感兴趣的:(Kotlin)