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

为什么Activity不能加入maindex中? #18

Open
Dwan-xie opened this issue Nov 10, 2016 · 40 comments
Open

为什么Activity不能加入maindex中? #18

Dwan-xie opened this issue Nov 10, 2016 · 40 comments
Labels

Comments

@Dwan-xie
Copy link

一开始加入了9个-just activity 可以正确分包
后来又加入了2个activity 这两个activity就不能被加入maindex

@TangXiaoLv
Copy link
Owner

@Dwan-xie 看下配置文件

@Dwan-xie Dwan-xie changed the title 为什么Activity并不能被加入maindex中? 为什么Activity不能加入maindex中? Nov 10, 2016
@Dwan-xie
Copy link
Author

Dwan-xie commented Nov 10, 2016

#为注释符

#-----------主Dex中必要依赖的脚本配置-----------
#默认保留四大组件中其他三大组件(并计算其依赖树),Activity组件选择性保留(使用-just activity 选项),若为空不保留任何Activity
-just activity com.babytree.apps.pregnancy.activity.SplashActivity
-just activity com.babytree.apps.pregnancy.activity.PregnancySplashActivity
-just activity com.babytree.apps.pregnancy.MainActivity
-just activity com.babytree.apps.pregnancy.activity.IntroduceActivity
-just activity com.babytree.apps.pregnancy.SailfishActivity
-just activity com.babytree.apps.pregnancy.activity.RoleSelectActivity
-just activity com.babytree.apps.pregnancy.activity.CalculatorActivity
-just activity com.babytree.apps.pregnancy.activity.BirthdaySelectActivity
-just activity com.babytree.apps.pregnancy.activity.SexSelectActivity
-just activity com.babytree.apps.pregnancy.activity.knowledge.base.KnowledgeViewPagerActivity;
-just activity com.babytree.apps.pregnancy.activity.knowledge.base.KnowledgeListActivity;

#-----------附加类-----------

如果你想要某个包路径在maindex中,则使用 -keep 选项,即使他已经在分包的路径中.若为空,不保留任意类

-keep com.babytree.apps.pregnancy.activity.knowledge.base.**

保留单个类.

-keep com.babytree.apps.pregnancy.db.LocationDbAdapter

这条配置可以指定这个包下类在第二及其他dex中.

#-split
#将全部类移出主Dex
-split .

不包含Android gradle 插件自动生成的miandex列表.(不使用建议的依赖树,注释掉表示使用,否则-just activity无效)

#-donot-use-suggest

(分割每个dex包的方法数上限) 扩展参数:例如 --set-max-idx-number=50000

如果出现 DexException: Too many classes in --main-dex-list, main dex capacity exceeded:

表明限制的方法数小于main dex的必要方法数,调大到合适数值即可

-dex-param --set-max-idx-number=50000

不进行dex分包, 直到 dex 的id数量超过 65536.(设置自动执行分包策略)

#-auto-maindex

显示miandex的日志.

-log-mainlist

@Dwan-xie
Copy link
Author

在红米2手机上出现各种类找不到,但其他手机都没有问题。而且我在maindexlist中都找到这些类?这种情况有遇到过吗?

@TangXiaoLv
Copy link
Owner

@Dwan-xie 我这边没有遇到过这种情况。红米2也测试过没问题,不知道你那边怎么配置的

@Dwan-xie
Copy link
Author

@TangXiaoLv 就是上面发的配置,红米2上不是activity类找不到而是一些其他引用类找不到,是否跟混淆有关?

@Dwan-xie
Copy link
Author

例如一些工具类等等的

@TangXiaoLv
Copy link
Owner

@Dwan-xie 混淆也是从mapping里拿的,你测试下不混淆跑在红米2上会不会有问题

@Dwan-xie
Copy link
Author

@TangXiaoLv 好的,您帮忙看一下我上面的配置是否写的有问题?

@TangXiaoLv
Copy link
Owner

理论上没问题,你可以把-dex-param --set-max-idx-number=50000注释掉看看,或者检查你的main dex中是否有缺少类

@Dwan-xie
Copy link
Author

@TangXiaoLv 我在maindexlist都能找到缺少的类,但这台手机就是混classnotfound

@Dwan-xie
Copy link
Author

@TangXiaoLv 出现了多次这个信息
-hasApp = true
-DexKnifePlugin Enable = true
-DexKnifePlugin checkProductFlavor = true
-DexKnifePlugin checkBuildType = true
-DexKnifePlugin buildType.name = debug
-DexKnifePlugin flavorName = babytree
-just activity size = 7
main-dex-filter: found task collectBabytreeDebugAndroidTestMultiDexComponents
main-dex-filter: found task collectBabytreeDebugMultiDexComponents
main-dex-filter: found task collectBabytreeReleaseMultiDexComponents
:preBuild UP-TO-DATE
:preBabytreeDebugBuild UP-TO-DATE
:checkBabytreeDebugManifest
-DexKnifePlugin Enable = false
-DexKnifePlugin Enable = false

@Dwan-xie
Copy link
Author

@TangXiaoLv 发现问题了,是混淆导致的。
project引用module的文件就会找不到。

@TangXiaoLv
Copy link
Owner

@Dwan-xie 好,我本地模拟下

@Dwan-xie
Copy link
Author

@TangXiaoLv 我们目录结构是旧的eclipse的,
project ->library->library,project再去获取最底层library的类的时候就出错了

@Dwan-xie
Copy link
Author

@TangXiaoLv 我调整了目录结构,变成了studio的样式,现在连mutlidex都打不进maindexlist了。。。。。

@TangXiaoLv
Copy link
Owner

@Dwan-xie 看下你的gradle 配置

@Dwan-xie
Copy link
Author

root gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
/**

  • all modules rely on these variables
    */
    ext {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.2"
    checkReleaseBuilds = false
    abortOnError = false
    }

buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.library.tangxiaolv:dexknife-plus:1.0.1'
classpath fileTree(dir: 'maa', include: ['*.jar'])
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
jcenter()
mavenCentral()
}
}

app gradle:
apply plugin: 'com.android.application'
apply plugin: 'maa'
apply plugin: 'dexknifePlus'

android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
lintOptions {
checkReleaseBuilds rootProject.ext.checkReleaseBuilds
abortOnError rootProject.ext.abortOnError
}

defaultConfig {
    applicationId "com.babytree.apps.pregnancy"
    minSdkVersion 16
    targetSdkVersion 22
    versionCode 301
    versionName '7.0.0-beta'
    multiDexEnabled true
    manifestPlaceholders = [UMENG_CHANNEL: "babytree"]
    ndk {
        abiFilters "armeabi"
    }
}

useLibrary 'org.apache.http.legacy'

signingConfigs {
    release {
        storeFile file("doc/babytree.keystore")
        storePassword 'babytree'
        keyAlias 'babytree'
        keyPassword 'babytree'
    }
}
productFlavors {
    babytree {

    }
}

productFlavors.all { flavor ->
    flavor.manifestPlaceholders = [UMENG_CHANNEL: name]
}

buildTypes {
    release {
        buildConfigField "boolean", "EMULATOR", "true"
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-android.txt'
        zipAlignEnabled true
        signingConfig signingConfigs.release
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    def fileName = "pregnancy-v2_${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
    }
    debug {
        buildConfigField "boolean", "EMULATOR", "false"
        signingConfig signingConfigs.release
    }
}
packagingOptions {
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
}

dexOptions {
    jumboMode = true
    preDexLibraries = false
    javaMaxHeapSize "2g"
}

}

dexKnife{
//必选参数
enabled true //if false,禁用分包插件
//可选参数
//1.如果没有可选参数,将根据enabled决定是否分包。
//2.如果有可选参数,需满足必选参数和可选参数的条件才允许分包
buildType 'release'

/*
*eg:当前productFlavors = dev,buildType = debug,
*参数组合1:enabled = true,productFlavor = dev,buildType = debug 分包
*参数组合2:enabled = true,productFlavor = mock,buildType = debug 不分包
*参数组合1:enabled = true,buildType = debug 所有buildType = debug分包
*参数组合1:enabled = true,productFlavor = dev 所有productFlavor = dev分包
* */

}

dependencies {
compile fileTree(include: ['*.jar'], exclude: ['org.simalliance.openmobileapi.jar'], dir: 'libs')
compile project(':meitun_lib')
provided files('libs/org.simalliance.openmobileapi.jar')
}

@Dwan-xie
Copy link
Author

library gradle:
apply plugin: 'com.android.library'

android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
lintOptions {
checkReleaseBuilds rootProject.ext.checkReleaseBuilds
abortOnError rootProject.ext.abortOnError
}

useLibrary 'org.apache.http.legacy'

packagingOptions {
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
}

}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:cardview-v7:23.1.1'
compile 'com.qiniu:happy-dns:0.2.7'
compile 'com.facebook.react:react-native:0.20.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'org.greenrobot:greendao:2.2.0'
compile 'com.android.support:multidex:1.0.1'
}

@TangXiaoLv
Copy link
Owner

@Dwan-xie 是module所有的依赖都找不到,还是个别的?

@Dwan-xie
Copy link
Author

@TangXiaoLv 目前来看是个别的,我开了log之后看到会出现很多次的
DexKnifePlugin Enable = true
DexKnifePlugin Enable = false
DexKnifePlugin Enable = false

@TangXiaoLv
Copy link
Owner

@Dwan-xie 正常,你有多个flavors就这样,只有一个当前的flavors才打开,

@TangXiaoLv
Copy link
Owner

@Dwan-xie 你可以把个别的单独keep

@TangXiaoLv
Copy link
Owner

@Dwan-xie 类似-keep com.babytree.apps.pregnancy.db.LocationDbAdapter.class

@Dwan-xie
Copy link
Author

@TangXiaoLv 我现在是单独keep的,但是有一个类我keep了还是会找不到。
我-keep com.babytree.platform.util.** 这个路径下的所有class,但还是里面有些类找不到

@TangXiaoLv
Copy link
Owner

TangXiaoLv commented Nov 18, 2016

@Dwan-xie 用studio 的apk分析工具 查看下 main dex里有没有包含你们的那个缺少类,排查下是加载dex问题还是打包dex问题,你那个bug手机是什么系统版本?

@Dwan-xie
Copy link
Author

Dwan-xie commented Nov 18, 2016

@TangXiaoLv 手机型号是红米2-4.4.4

@TangXiaoLv
Copy link
Owner

@Dwan-xie 没打进去com.babytree.apps.pregnancy.utils.d

@Dwan-xie
Copy link
Author

@TangXiaoLv 请教一个问题,这个依赖关系不是由build-tools帮我们生成的吗?

@TangXiaoLv
Copy link
Owner

@Dwan-xie 能动态计算的依赖关系只能是-just activity 里的,-keep的不计算依赖关系,单纯的保留单个类文件

@Dwan-xie
Copy link
Author

@TangXiaoLv application中的依赖关系也是不计算的吗?需要我们手动放入?

@TangXiaoLv
Copy link
Owner

@Dwan-xie 如果你的类在activity里并且just 了,可以被计算出来,如果在keep的类里,依赖是计算不出的,需要单独keep

@Dwan-xie
Copy link
Author

@TangXiaoLv 那大概明白了,这些找不到的类都是application中初始化的一些类,activity的依赖类基本都没问题

@TangXiaoLv
Copy link
Owner

@Dwan-xie application,service、content provider、broadcast receiver,默认全部动态计算加载依赖,activity手动指定

@TangXiaoLv
Copy link
Owner

@Dwan-xie 一般出现几个找不到的依赖直接keep就好了

@Dwan-xie
Copy link
Author

Dwan-xie commented Nov 18, 2016

@TangXiaoLv 那就不应该了呀,这个utils类是在appliaction中初始化的,它的依赖关系不应该不需要我们来单独处理么?
public class PregnancyApplication extends BabytreeMusicPlayApplication {
@OverRide
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}

@Override
public void onCreate() {
    super.onCreate();
        ColdStartupUtil.initTCAgent(this);
    }

@TangXiaoLv
Copy link
Owner

@Dwan-xie 你那个是几级依赖层级

@Dwan-xie
Copy link
Author

@TangXiaoLv 这次这个报错com.babytree.apps.pregnancy.utils.d,是在project里面的PregnancyApplication ,应该算是第一层级
还有一个我加了com.babytree.platform.util.t,是在第三级的library里baseAppliaction

@Dwan-xie
Copy link
Author

Could not find class 'com.babytree.apps.pregnancy.activity.knowledge.base.a.a', referenced from method com.babytree.apps.pregnancy.PregnancyApplication.c
Could not find class 'com.babytree.apps.pregnancy.activity.knowledge.base.a.b', referenced from method com.babytree.apps.pregnancy.PregnancyApplication.d
Could not find class 'com.babytree.apps.pregnancy.f.b', referenced from method com.babytree.apps.pregnancy.PregnancyApplication.b
Could not find class 'com.babytree.apps.pregnancy.f.b', referenced from method com.babytree.apps.pregnancy.PregnancyApplication.onCreate

我上传了一下maindex,这几个类都能在maindexlist找到,不知道为什么了。。。。
maindexlist.txt

@TangXiaoLv
Copy link
Owner

@Dwan-xie
keep 和 split 使用的是未混淆的类路径和类名;
检查下编译后的main dex中是否有你的类,ProGuard有些选项会删除你未引用的类;
gradle console输出窗口,混淆后 dexknife应有 DexKnife: From Mapping 的红色文字提示,打开log选项,检查下dexknife的分包日志;

关闭分包插件,强迫编译器默认分包,看下是否有出错;

class no def 一般是由于你的proguard-rules 的配置不当,或者multidex功能错误照成,DexKnife只生成dex 的maindexlist,不参与编译过程,即使你不使用DexKnife,手动编写maindexlist,一样也有可能会遇到类似的问题。

@JarvisGG
Copy link

JarvisGG commented Dec 6, 2020

在红米2手机上出现各种类找不到,但其他手机都没有问题。而且我在maindexlist中都找到这些类?这种情况有遇到过吗?

看下你的 MultiDex install 是在哪执行的

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

No branches or pull requests

3 participants