使用Gradle的implementation替代compile后无法访问库模块依赖
问题原因与解决方案
这其实是Gradle中implementation和api(原compile)这两个依赖配置关键字的核心区别导致的,我来给你拆解清楚:
为什么会出现这个问题?
- 当你用旧的
compile配置framework模块的依赖时,这些依赖会被传递暴露给依赖framework的app模块,所以app里能直接调用这些第三方库的类和方法。 - 但换成
implementation后,Gradle会把这些依赖完全隐藏在framework模块内部——只有framework自己能访问这些库,上层的app模块看不到它们,自然就无法直接调用了。
怎么解决?
根据你的实际需求,有两种可选方案:
方案1:把需要暴露的依赖改成api
如果你确实需要在app模块中直接使用framework里的这些第三方库(比如Retrofit、EventBus),那把framework的依赖配置里对应的implementation换成api即可(api是官方推荐用来替代旧compile的关键字):
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) api 'com.android.support:appcompat-v7:27.1.1' api 'com.android.support:support-v4:27.1.1' api 'com.android.support:design:27.1.1' api 'com.squareup.retrofit2:retrofit:2.3.0' api 'com.squareup.retrofit2:converter-gson:2.3.0' api 'com.squareup.okhttp3:okhttp:3.10.0' api 'com.squareup.okhttp3:logging-interceptor:3.9.0' api 'com.google.code.gson:gson:2.8.2' api 'io.reactivex.rxjava2:rxjava:2.1.1' api 'io.reactivex.rxjava2:rxandroid:2.0.1' api 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' api 'org.greenrobot:eventbus:3.1.1' }
修改后,app模块依赖framework时就能像之前用compile一样,直接访问这些第三方库了。
方案2:封装framework功能,隔离第三方依赖
如果从架构设计角度,你希望framework模块承担封装职责,不让app直接依赖第三方库,那可以保持implementation不变——在framework里把第三方库的功能封装成上层可用的接口,比如把Retrofit的网络请求封装成NetworkManager,把EventBus的操作封装成EventBusHelper,然后app只调用这些封装好的类,不用直接操作第三方库。这种方式能降低app和第三方库的耦合度,更符合模块化的设计思想。
小提示
Gradle已经废弃了旧的compile关键字,官方明确推荐用api(对应传递依赖场景)和implementation(对应内部依赖隔离场景)来替代,所以优先用api而不是compile哦。
内容的提问来源于stack exchange,提问作者ND1010_
相关产品推荐
相关产品推荐

