背景
前一阵用Android Studio开发了一个app,用到了eclipse paho来实现MQTT通信部分;
在引入库时,在build.gradle中添加:
dependencies {
...
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
}
运行时却闪退:
02-04 05:52:40.411 7117 7117 D AndroidRuntime: Shutting down VM
02-04 05:52:40.416 7117 7117 E AndroidRuntime: FATAL EXCEPTION: main
02-04 05:52:40.416 7117 7117 E AndroidRuntime: Process: xxx, PID: 7117
02-04 05:52:40.416 7117 7117 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/LocalBroadcastManager;
02-04 05:52:40.416 7117 7117 E AndroidRuntime: at org.eclipse.paho.android.service.MqttAndroidClient.registerReceiver(MqttAndroidClient.java:450)
02-04 05:52:40.416 7117 7117 E AndroidRuntime: at org.eclipse.paho.android.service.MqttAndroidClient.connect(MqttAndroidClient.java:428)
...
然而,同样的代码,同样的引用方式,我将其复制到一个新建的Android项目中(demo),可以正常运行;
因此怀疑是gradle配置差异;
通过上网查询+比对,最后确认是gradle.properties中如下两个属性的差异:
android.useAndroidX=true
android.enableJetifier=true
根据
Android官网
介绍:
android.useAndroidX=true 表示“Android插件会使用对应的AndroidX库,而非Support库”;未设置时默认为false;
android.enableJetifier=true 表示Android插件会通过重写其二进制文件来自动迁移现有的第三方库,以使用AndroidX依赖项;未设置时默认为false;
当然,这两个属性对Android Sutio版本是有要求的:
3.2
同时,由于Android Studio的版本对gradle、gradle plugin的最低版本也有限制,因此可以认为对gradle及其插件也是有要求的:
-
将 Android studio 升级到 3.2 及以上;(我使用的3.6.3)
-
Gradle 插件版本改为 4.6 及以上;(我使用的4.6)
-
compileSdkVersion 版本升级到 28 及以上;(我使用的30)
-
buildToolsVersion 版本改为 28.0.2 及以上;(我使用的30.0.3)
关于gradle和gradle plugin的版本信息,可以在这里查找:
Gradle:
https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google
Gradle Plugin:
https://services.gradle.org/distributions/
回到开头的那个问题,我们通过build debug版本apk进行分析,来确认android.useAndroidX=true与android.enableJetifier=true的效果:
添加属性前:
修改后:
可以看到invoke-static {v1}这一段的主体,从support v4的LocalBroadcaseManager变为了androidx的LocalBroadcaseManager,与官网描述一致;
再次编译部署,闪退问题消失;