Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

app对lib的间接依赖无效 #117

Closed
tcking opened this issue Apr 25, 2016 · 29 comments
Closed

app对lib的间接依赖无效 #117

tcking opened this issue Apr 25, 2016 · 29 comments

Comments

@tcking
Copy link
Contributor

tcking commented Apr 25, 2016

前提条件:
1.工程 lib.common 引入第三方的依赖 ,例如compile 'com.facebook.fresco:fresco:0.9.0+'
2.工程 lib.base 依赖lib.common compile project(':lib.common')

问题:
在执行buildLib时提示找不到com.facebook.fresco中的类 (AS没有提示错误,app能单独跑)

期望:
app引用了lib工程,lib引用了其他lib工程的依赖能作用于app,例如对compile 'com.android.support:appcompat-v7:23.3.0'的引用只需要在一个lib引用,如app间接引用了此lib,则不需要再dependencies中引用 (目前每个app都需要声明依赖)

@peacepassion
Copy link
Contributor

你是说buildLib过程中,lib.base的编译会因为找不到com.facebook.fresco的类失败?

那buildLib的时候,是lib.base先执行的还是lib.common先执行的?

@tcking
Copy link
Contributor Author

tcking commented Apr 25, 2016

从gradle的日志看lib.common先执行,并且生成了so文件,打开so中的dex文件这些依赖的类都在

@peacepassion
Copy link
Contributor

那就奇怪了。 fresco应该是一个aar依赖,检查一下buildLib之后,build-small/intermediates/small-pre-jar/base/ 下面有没有fresco的jar?

@tcking
Copy link
Contributor Author

tcking commented Apr 26, 2016

有的

@peacepassion
Copy link
Contributor

能否把项目上传到github上,我拉下来跑一下

@tcking
Copy link
Contributor Author

tcking commented Apr 26, 2016

@galenlin
Copy link
Member

@peacepassion @tcking 看了下 还是lib.*间编译顺序的问题。

  1. AS module间的evaluate顺序根据字母排序,lib.base优先
  2. 由于lib.base在evaluate期间需要先声明好provided的jars(build-small/small-pre-jar/base),但是lib.common还未编译好,该目录无文件

于是AppPlugin#resolveReleaseDependencies中语句:

// Pre-split shared libraries at release mode
//  - host, appcompat and etc.
def baseJars = project.fileTree(dir: rootExt.preBaseJarDir, include: ['*.jar'])
project.dependencies.add('provided', baseJars)

无法正确遍历到fresco等jar并添加至依赖,导致错误。

@peacepassion
Copy link
Contributor

确实有问题,
image

provide依赖是在project.afterEvaluate添加进去的,而在第一次buildLib的时候,build-small/small-pre-jar/base还是空的,因此,lib的依赖是无效的。

再次buildLib,就能够找到fresco了,但是还发现另外一个bug,找不到v4下的一个东西
image

原因是,v4下面有两个jar,我们只拷贝了classes.jar, 是不够的
image

@peacepassion
Copy link
Contributor

aar依赖这个东西真的好复杂…………

这里还没有涉及到版本冲突问题,如果版本不一致的话,肯定还会有更微妙的问题......

@galenlin
Copy link
Member

@peacepassion 对,这个我也发现了哈。jars/libs/*.jar的拷贝容易修正,不过第一个问题不好解决。。

@peacepassion
Copy link
Contributor

@galenlin 改为prebuild.doFirst的时候,resovleDenpendency是否可行?

@tcking
Copy link
Contributor Author

tcking commented Apr 26, 2016

依赖管理需通过工程结构上统一管理,不允许apk插件引入第三方依赖,build的时如果发现多次引入build应该直接失败,这也是我想通过这种方式来组织工程的原因

@galenlin
Copy link
Member

似乎不行,以前试过evaluate完成后无法重新设置

@tcking
Copy link
Contributor Author

tcking commented Apr 26, 2016

根据这个思路,把lib.base修改为lib.didibase,错误还是一样

看了下 还是lib.*间编译顺序的问题。

AS module间的evaluate顺序根据字母排序,lib.base优先
由于lib.base在evaluate期间需要先声明好provided的jars(build-small/small-pre-jar/base),但是>lib.common还未编译好,该目录无文件
于是AppPlugin#resolveReleaseDependencies中语句:

// Pre-split shared libraries at release mode
// - host, appcompat and etc.

def baseJars = project.fileTree(dir: rootExt.preBaseJarDir, include: ['*.jar'])
project.dependencies.add('provided', baseJars)
无法正确遍历到fresco等jar并添加至依赖,导致错误。

@galenlin
Copy link
Member

@tcking evaluate顺序调整后,还需要改写 baseJars的收集方式,因为直接通过fileTree遍历preBaseJarDir目录是暂时无结果的-还未编译生成。

需要通过某种方式(DependencyUtils.getAllDependencies)先得到各jar的名称然后手动拼接路径。

不过这种方法还是有局限,我在尝试用 artifacts + configuration的方法看能否解决。

// AppPlugin
compileLibs.each {
    Project lib = it.dependencyProject
    project.dependencies {
        provided project(path: lib.path, configuration: 'jars')
    }
}

@galenlin
Copy link
Member

@tcking @peacepassion
Jesus! This save our life! 😃

@peacepassion
Copy link
Contributor

我测了一下,OK了。
Brilliant work. 👍

@tcking
Copy link
Contributor Author

tcking commented Apr 27, 2016

太好了,编译正常通过!
不过在集成fresco的时候,在运输时抛出了一个异常:

04-27 18:08:56.957 31799-31799/com.didi.pacific E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.didi.pacific, PID: 31799
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.didi.pacific/com.didi.pacific.app.main.activity.MainActivity}: android.view.InflateException: Binary XML file line #31: Error inflating class com.facebook.drawee.view.SimpleDraweeView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2464)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526)
at android.app.ActivityThread.access$800(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5549)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Caused by: android.view.InflateException: Binary XML file line #31: Error inflating class com.facebook.drawee.view.SimpleDraweeView
at android.view.LayoutInflater.createView(LayoutInflater.java:637)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:747)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:810)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.inflate(LayoutInflater.java:508)
at android.view.LayoutInflater.inflate(LayoutInflater.java:418)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136)
at com.didi.pacific.app.main.activity.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:5977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
at net.wequick.small.ApkBundleLauncher$InstrumentationWrapper.callActivityOnCreate(ApkBundleLauncher.java:160)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526) 
at android.app.ActivityThread.access$800(ActivityThread.java:169) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5549) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:611)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:747) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:810) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:508) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:418) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136) 
at com.didi.pacific.app.main.activity.MainActivity.onCreate(MainActivity.java:20) 
at android.app.Activity.performCreate(Activity.java:5977) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111) 
at net.wequick.small.ApkBundleLauncher$InstrumentationWrapper.callActivityOnCreate(ApkBundleLauncher.java:160) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526) 
at android.app.ActivityThread.access$800(ActivityThread.java:169) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5549) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/facebook/drawee/R$styleable;
at com.facebook.drawee.view.GenericDraweeView.inflateHierarchy(GenericDraweeView.java:127)
at com.facebook.drawee.view.GenericDraweeView.<init>(GenericDraweeView.java:75)
at com.facebook.drawee.view.SimpleDraweeView.<init>(SimpleDraweeView.java:60)
at java.lang.reflect.Constructor.newInstance(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
at android.view.LayoutInflater.createView(LayoutInflater.java:611) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:747) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:810) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:508) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:418) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136) 
at com.didi.pacific.app.main.activity.MainActivity.onCreate(MainActivity.java:20) 
at android.app.Activity.performCreate(Activity.java:5977) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111) 
at net.wequick.small.ApkBundleLauncher$InstrumentationWrapper.callActivityOnCreate(ApkBundleLauncher.java:160) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526) 
at android.app.ActivityThread.access$800(ActivityThread.java:169) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5549) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.facebook.drawee.R$styleable" on path: DexPathList[[zip file "/data/app/com.didi.pacific-2/lib/arm/libcom_didi_pacific_app_main.so", zip file "/data/app/com.didi.pacific-2/lib/arm/libcom_didi_pacific_lib_didibase.so", zip file "/data/app/com.didi.pacific-2/lib/arm/libcom_didi_pacific_lib_common.so", zip file "/data/app/com.didi.pacific-2/base.apk"],nativeLibraryDirectories=[/data/app/com.didi.pacific-2/lib/arm, /vendor/lib, /system/lib, /data/data/com.didi.pacific/files/storage/com.didi.pacific.lib.common/lib/armeabi-v7a, /data/data/com.didi.pacific/files/storage/com.didi.pacific.app.main/lib/armeabi-v7a]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.facebook.drawee.view.GenericDraweeView.inflateHierarchy(GenericDraweeView.java:127) 
at com.facebook.drawee.view.GenericDraweeView.<init>(GenericDraweeView.java:75) 
at com.facebook.drawee.view.SimpleDraweeView.<init>(SimpleDraweeView.java:60) 
at java.lang.reflect.Constructor.newInstance(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
at android.view.LayoutInflater.createView(LayoutInflater.java:611) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:747) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:810) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:508) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:418) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136) 
at com.didi.pacific.app.main.activity.MainActivity.onCreate(MainActivity.java:20) 
at android.app.Activity.performCreate(Activity.java:5977) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111) 
at net.wequick.small.ApkBundleLauncher$InstrumentationWrapper.callActivityOnCreate(ApkBundleLauncher.java:160) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2526) 
at android.app.ActivityThread.access$800(ActivityThread.java:169) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:194) 
at android.app.ActivityThread.main(ActivityThread.java:5549) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 
    Suppressed: java.lang.ClassNotFoundException: com.facebook.drawee.R$styleable
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        at java.lang.ClassLoader.loadClass(ClassLoade

@peacepassion
Copy link
Contributor

这个是因为目前lib/bundle依赖aar的时候,没有将aar所生成的R.java打进包里面。 参见 #119

@tcking
Copy link
Contributor Author

tcking commented Apr 27, 2016

对于这种问题,有一个思路:
1.所有(包括app.*)对第三方的依赖全部在宿主中声明
2.app.*在开发阶段需要引入app中所有的dependencies (可以通过自定义gradle插件来做,类似自动把small引入到app.*的编译dependencies中)

@galenlin
Copy link
Member

@tcking 在宿主里都写好应该是没问题的,这个自动处理的逻辑是有的了。

@galenlin
Copy link
Member

现在麻烦的是对于要做成lib.*独立一个插件出来的需求,需要特殊处理下。

@tcking
Copy link
Contributor Author

tcking commented Apr 27, 2016

@galenlin 我的想法是这样的:

期望:
1.所有对第三方的依赖统一在一个地方设置,app.*无需单独设置也不允许引入第三方依赖,例如compile 'com.android.support:appcompat-v7:23.3.0',compile 'org.greenrobot:eventbus:3.0.0'
2.lib.base作为公共部分,是各插件的解耦层,例如定义好的event,BaseActivty等,各插件也需要能访问到lib.base中所有的类

目前的现状:
1.app 宿主dependencies中声明所有其他app.* 所需要的compile,在AS中lib.base中无法访问app 宿主dependencies的类
2.在AS中,app.* 无法访问app 宿主dependencies的类

@galenlin
Copy link
Member

恩,现在设计是这样的:

  1. appcompat,design等官方包放宿主(插件module在新建的时候其实会自动带compat/design的)
  2. fresco, eventbus等第三方库以及业务公共库放lib.*app.*可以compile project(':lib.xx')

这样理论上可以满足大部分需求了。

@tcking
Copy link
Contributor Author

tcking commented Apr 28, 2016

这样做会有一个问题:lib.* 中可能需要用到appcompat,例如BaseActivity,但是lib.* 不能 compile project(':app') 因为app是application而不是library,此时则需要在lib.* 中再次声明对appcompat的依赖,也就是同一个依赖多处地方声明。所以这样应该更合理些
.lib.*中能引用arr类型的依赖,则所有依赖声明在lib.common中,app包括app.*也依赖此工程
目前要解决的问题就是在lib.* 中不能使用aar类型的依赖

@skylz
Copy link

skylz commented Apr 29, 2016

@tcking ,lib._依赖aar,把aar 当做lib._先编译一下,然后开发的时候依赖aar,真正编译的时候用编译出来的so包(类似于依赖android.jar),应该可以解决依赖aar的问题

@tcking
Copy link
Contributor Author

tcking commented Apr 29, 2016

@skylz 没太理解这个过程,可否详细的描述下

@zc2721
Copy link

zc2721 commented Apr 12, 2017

方法数过多,在4.x的手机上会出现ClassNotFoundException,看http://blog.csdn.net/jia635/article/details/55103846

@jasonsz
Copy link

jasonsz commented May 19, 2018

@galenlin @peacepassion 请问一下,项目中有moduelA和moduleB,ModuleA依赖了ModuelB,这个moduleB依赖了Fresco。moduleA依赖moduleB,如果在build.gradle中写成compile project(':moduleB')是可以正常运行的。如果如果我把ModuelB打成一个aar的sdk形式,这个时候放到ModuleA的libs里面去依赖,就会报错:找不到com.facebook.drawee.view.SimpleDraweeView的类文件。这个怎么解?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants