จำนวนวิธีการอ้างอิงในไฟล์. dex ต้องไม่เกิน 64k API 17


154

ฉันกำลังสร้างแอปด้วย SugarORM Library แต่เมื่อฉันพยายามสร้างโครงการสำหรับ API 17 (ไม่ได้ตรวจสอบผู้อื่น) มันแสดงข้อผิดพลาดในการสร้าง

    Information:Gradle tasks [:app:assembleDebug]
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72330Library UP-TO-DATE
:app:prepareComAndroidSupportCardviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportDesign2330Library UP-TO-DATE
:app:prepareComAndroidSupportMediarouterV72300Library UP-TO-DATE
:app:prepareComAndroidSupportRecyclerviewV72330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidVolleyVolley100Library UP-TO-DATE
:app:prepareComGithubSatyanSugar14Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServices840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAds840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAnalytics840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppindexing840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppinvite840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAppstate840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesAuth840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBase840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesBasement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesCast840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesDrive840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesFitness840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGames840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesGcm840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesIdentity840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesLocation840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMaps840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesMeasurement840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesNearby840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPanorama840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesPlus840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesSafetynet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesVision840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWallet840Library UP-TO-DATE
:app:prepareComGoogleAndroidGmsPlayServicesWearable840Library UP-TO-DATE
:app:prepareMeDrakeetMaterialdialogLibrary131Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:prePackageMarkerForDebug
:app:transformClassesWithDexForDebug
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2
Information:BUILD FAILED
Information:Total time: 21.663 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console

แต่เมื่อฉันสร้างโครงการนี้สำหรับ Android v5.0 ขึ้นไปมันใช้งานได้ดี หากฉันลบการพึ่งพาระดับเสียงของ SugarORM มันจะทำงานได้ดีสำหรับทั้งอุปกรณ์ v4.2.2 และ v5.0


1
developer.android.com/tools/building/multidex.html ตรวจสอบนี้
Raghunandan

ลองใช้ proguard ลิงค์นี้android-arsenal.com/details/1/337ระบุการใช้ SugarORM กับ proguard
Shaan_B

19
เพิ่งได้รับหลังจากอัปเกรดเป็น api 23 มันเป็นไปไม่ได้เลยที่จะมีประสิทธิภาพกับ Android ทุก sdk แบ่งเนื้อหา ทุกการอัปเดตเป็น AS จะแบ่งเนื้อหา ข้อความแสดงข้อผิดพลาดใช้ไม่ได้ เสียเหมือนกัน ขยะมูลฝอยขยะมูลฝอย
RunLoop

1
@ RunLoop ไม่ได้หวังว่าจะหายไป .... ฉันพบว่า Android เป็นแพลตฟอร์มที่ดีที่สุดเท่าที่เคยมีการพัฒนา .... Moch ยืดหยุ่นและทรงพลัง .... เพราะคุณจะทำให้มือของคุณสกปรกในการเข้ารหัส .... มันจะดี .... ทุกข้อผิดพลาดมีประโยชน์ แต่ต้องเข้าใจข้อความ
Sandeep Singh Rana

2
@ บาลาจข่านOne or more of the answers is exemplary and worthy of an additional bounty.Just to the point and accurate answer.ฉันขอแนะนำคำตอบ (และยอมรับ) ชั้นนำ!
Jon Goodwin

คำตอบ:


331

คุณมีวิธีมากเกินไป dexมีเพียง65536 วิธีเท่านั้น

เป็นข้อเสนอแนะคุณสามารถใช้การสนับสนุน multidex

เพียงเพิ่มบรรทัดเหล่านี้ในmodule/build.gradle:

android {

    defaultConfig {
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  implementation 'com.android.support:multidex:1.0.3'  //with support libraries
  //implementation 'androidx.multidex:multidex:2.0.1'  //with androidx libraries
}

นอกจากนี้ในการManifestเพิ่มMultiDexApplicationคลาสของคุณจากไลบรารีการสนับสนุน multidex ไปยังองค์ประกอบแอปพลิเคชัน

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.android.multidex.myapplication">
        <application
            ...
            android:name="android.support.multidex.MultiDexApplication">

            <!-- If you are using androidx use android:name="androidx.multidex.MultiDexApplication" -->

            <!--If you are using your own custom Application class then extend -->
            <!--MultiDexApplication and change above line as-->
            <!--android:name=".YourCustomApplicationClass"> -->

            ...
        </application>
    </manifest>

หากคุณกำลังใช้ของคุณเองApplicationระดับเปลี่ยนระดับผู้ปกครองจากไปApplication หากคุณไม่สามารถทำได้ในคลาส Application ของคุณจะแทนที่เมธอดด้วย:MultiDexApplication
attachBaseContext

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    MultiDex.install(this);
}

อีกวิธีหนึ่งคือพยายามลบรหัสที่ไม่ได้ใช้ด้วยProGuard - กำหนดค่าการตั้งค่าProGuardสำหรับแอปของคุณเพื่อเรียกใช้ ProGuard และให้แน่ใจว่าคุณเปิดใช้งานการหดตัวสำหรับรุ่นบิลด์


1
@Override ที่ได้รับการป้องกันเป็นโมฆะ attachBaseContext (บริบท newBase) {super.attachBaseContext (newBase); MultiDex.install (นี้); } override
Sandeep Singh Rana

1
การคลิก Cmd MultiDexApplication ฉันเห็นไฟล์. class ที่ decompiled แล้วนั้นจะทำการแทนที่ไฟล์ ดังนั้นจึงไม่จำเป็นที่จะต้องยกเลิกมันอีกครั้งฉันเดา ..
Mete

4
ถ้าฉันไม่มีวิธีมากเกินไป ฉันไม่มีวิธีการมากมายในแอพของฉัน ฉันเชื่อว่ามันไม่ถึงขนาดนั้น
นีออน

6
ฉันทำสองส่วนนี้เท่านั้น: "multiDexEnabled จริง" และคอมไพล์ 'com.android.support:multidex:1.0.0' ในไฟล์ build.grandle ของฉัน ฉันไม่จำเป็นต้องเปลี่ยนแปลงอะไรในไฟล์ Manifest หรือทำสิ่งอื่น ๆ ที่คุณพูดถึงเรื่องการเอาชนะ attachBaseContext ฯลฯ แต่โซลูชันของคุณแก้ไขปัญหาให้ฉันได้! ขอบคุณ
Jaime Montoya

2
@NeonWarge น่าจะเป็นเพราะการพึ่งพาของคุณ บางทีคุณได้รวมบริการ Google Play ทั้งหมดหรือไม่ ตรวจสอบคำตอบ
mr5

132

ใน android / app / build.gradle

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

วางสิ่งนี้ไว้ใน defaultConfig ของคุณ:

multiDexEnabled true 

มันใช้งานได้สำหรับฉัน


3
นี่สำหรับ Lollipop หรือสูงกว่าเท่านั้นใช่ไหม
Vic Torious

1
มันทำให้การสร้างสำเร็จ แต่แอปขัดข้องหลังจากเปิดตัว
Vasanth

18

ฉันได้รับข้อความแสดงข้อผิดพลาดนี้เนื่องจากในขณะที่กำลังเขียนโค้ดคอมไพล์การอัพเดตอัตโนมัติในโปรเจ็กต์ในbuild.gradleไฟล์

android {
    ...
    buildToolsVersion "23.0.2"
    ...
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:23.4.0' }

แก้ไขโดยแก้ไขรุ่น:

android {
        ...
        buildToolsVersion "23.0.2"
        ...
    }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
}

2
ฉันกำลังสร้างแอปง่าย ๆ ซึ่งใช้งานได้ดีจนกระทั่งฉันลองติดตามการสอนของ Google Map Objects ทันใดนั้นฉันก็ไม่สามารถรวบรวมได้อีก วิธีนี้ได้แก้ไขที่สำหรับฉัน คุณทำงานออกมาเป็นอย่างไรในโลก?
maccaroo

4
วิธีนี้ใช้ได้ผลดีเพราะห้องสมุดคอมไพล์ใหม่มีเมธอดมากเกินไป (เกิน 65536) และไลบรารี่เก่าไม่มี ดังนั้นมันเป็นเพียงแค่การแก้ไขอย่างรวดเร็วไม่ช้าก็เร็วคุณควรแก้ไขด้วยการเพิ่มการสนับสนุนมัลติไทด์เช่นคำตอบที่ยอมรับได้
Quan Nguyen

15

นี่คือสิ่งที่ได้ผลสำหรับฉัน:

สิ่งนี้เกิดขึ้นเนื่องจากมีวิธีที่ไม่ได้ใช้มากเกินไป วิธีการเหล่านี้ส่วนใหญ่มาจากห้องสมุดที่รวมอยู่ใน build.gradle ของคุณ

ใช้ทรัพยากรย่อและหดเพื่อแก้ไขปัญหานี้ด้วยการไล่ระดับสีและล้างรหัสของคุณในเวลาเดียวกัน

buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled true
            shrinkResources true
        }
    }

13

เปลี่ยน build.gradle ระดับแอป:

android {

compileSdkVersion 23

 buildToolsVersion '23.0.0'

    defaultConfig {
        applicationId "com.dkm.example"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }

มันใช้งานได้สำหรับฉัน


ใช่มันเป็นปัญหาเก่า แต่สำหรับ API รุ่นสุดท้ายเราต้องการmultiDexEnabledตัวเลือกเท่านั้นโดยไม่ต้องพึ่งพาหรือเปลี่ยนแปลงไฟล์รายการ
Hpsaturn

11

ข้อผิดพลาดนี้ยังสามารถเกิดขึ้นได้เมื่อคุณโหลด apis บริการ Google Play ทั้งหมดเมื่อคุณใช้เพียงไม่กี่ครั้ง

ตามที่ระบุไว้โดย google: "ในเวอร์ชันของบริการ Google Play ก่อนหน้า 6.5 คุณต้องรวบรวมแพคเกจทั้งหมดของ APIs ลงในแอพของคุณในบางกรณีการทำเช่นนั้นทำให้ยากที่จะรักษาจำนวนวิธีในแอปของคุณ (รวมถึง API เฟรมเวิร์กวิธีการไลบรารีและรหัสของคุณเอง) ภายใต้ขีด จำกัด 65,536

จากเวอร์ชัน 6.5 คุณสามารถรวบรวม API บริการของ Google Play ลงในแอพของคุณแทน "

ตัวอย่างเช่นเมื่อแอปของคุณต้องการ play-services-maps, play-services-location คุณต้องเพิ่ม apis เพียงสองไฟล์ในไฟล์ build.gradle ของคุณที่ระดับแอปดังแสดงด้านล่าง:

compile 'com.google.android.gms:play-services-maps:10.2.1'
compile 'com.google.android.gms:play-services-location:10.2.1'

แทน:

compile 'com.google.android.gms:play-services:10.2.1'

สำหรับเอกสารฉบับเต็มและรายชื่อบริการ google play apis คลิกที่นี่


9

เมื่อการอ้างอิงแอปของคุณมีมากกว่า65,536วิธีคุณจะพบข้อผิดพลาดของบิลด์ที่ระบุว่าแอปของคุณถึงขีด จำกัด ของสถาปัตยกรรมการสร้าง Android

รองรับ Multidex ก่อน Android 5.0

เวอร์ชันของแพลตฟอร์มก่อน Android 5.0 (API ระดับ 21) ใช้รันไทม์ Dalvik สำหรับการเรียกใช้โค้ดแอป โดยค่าเริ่มต้น Dalvik จำกัด แอปไว้ที่ไฟล์ classdex bytecode ไฟล์เดียวต่อ APK เพื่อหลีกเลี่ยงข้อ จำกัด นี้คุณสามารถเพิ่มไลบรารีการสนับสนุน multidex ในโครงการของคุณ:

dependencies {
  implementation 'com.android.support:multidex:1.0.3'
}

รองรับ Multidex สำหรับ Android 5.0 ขึ้นไป

Android 5.0 (API ระดับ 21) ขึ้นไปใช้รันไทม์ชื่อ ART ซึ่งรองรับการโหลดไฟล์ DEX หลายไฟล์จากไฟล์ APK ดังนั้นหาก minSdkVersion ของคุณคือ 21 หรือสูงกว่าคุณไม่จำเป็นต้องมีไลบรารีการสนับสนุนmultidex

หลีกเลี่ยงการ จำกัด 64K

  • ลบรหัสที่ไม่ได้ใช้ด้วย ProGuard - เปิดใช้งานการย่อขนาดโค้ด

กำหนดค่า multidex ในแอพสำหรับ

หาก minSdkVersion ของคุณตั้งไว้ที่ 21 หรือสูงกว่าสิ่งที่คุณต้องทำคือตั้งค่า multiDexEnabled เป็น true ในไฟล์ build.gradle ระดับโมดูลของคุณ

android {
defaultConfig {
    ...
    minSdkVersion 21 
    targetSdkVersion 28
    multiDexEnabled true
  }
 ...
}

หาก minSdkVersion ของคุณถูกตั้งค่าเป็น 20 หรือต่ำกว่าคุณต้องใช้ไลบรารีการสนับสนุน multidex

android {
defaultConfig {
    ...
    minSdkVersion 15 
    targetSdkVersion 28
    multiDexEnabled true
   }
   ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.3'
}

แทนที่คลาสแอปพลิเคชันเปลี่ยนเป็นขยายMultiDexApplication (ถ้าเป็นไปได้) ดังนี้:

public class MyApplication extends MultiDexApplication { ... }

เพิ่มไปยังไฟล์รายการ

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application
            android:name="MyApplication" >
        ...
    </application>
</manifest>

8

ฉันประสบปัญหาเดียวกันและสำหรับการสนับสนุนหลายระดับคุณต้องคำนึงถึงminSdkVersionของแอปพลิเคชันของคุณ หากคุณใช้minSdkVersion 21ขึ้นไปให้เขียนmultiDexEnabled จริงเช่นนี้

defaultConfig {
    applicationId *******************
    minSdkVersion 21
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

มันใช้งานได้สำหรับฉันและถ้าคุณใช้minSdkVersionต่ำกว่า 21 (ด้านล่างlolipop ) คุณต้องทำสองสิ่งที่ง่ายเป็นพิเศษ

1.เพิ่มการพึ่งพานี้ก่อน

รวบรวม 'com.android.support:multidex:1.0.1'

ใน build.gradle ของคุณ

2.บรรทัดสุดท้ายและวินาทีให้เพิ่มบรรทัดด้านล่างนี้ลงในใบสมัครของคุณ

หุ่นยนต์: name = "android.support.multidex.MultiDexApplication"

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:name="android.support.multidex.MultiDexApplication"
    android:theme="@style/AppTheme" >
    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Bingo แล้วมันจะทำงานในเวอร์ชั่นต่ำกว่าด้วย .. :) Happy coding


1

เป็นเพียงความคิดเห็นด้านข้างก่อนเพิ่มการสนับสนุนสำหรับ multidex - ตรวจสอบให้แน่ใจว่าคุณไม่ได้เพิ่มการพึ่งพาที่ไม่จำเป็น

ตัวอย่างเช่นในคู่มือวิเคราะห์ Facebook อย่างเป็นทางการ

พวกเขาระบุอย่างชัดเจนว่าคุณควรเพิ่มการพึ่งพาต่อไปนี้:

implementation 'com.facebook.android:facebook-android-sdk:[4,5)'

ซึ่งเป็นFacebookSDK ทั้งหมดจริง ๆ- ดังนั้นหากคุณต้องการตัวอย่างเพียงแค่การวิเคราะห์คุณต้องแทนที่ด้วย:

implementation 'com.facebook.android:facebook-core:5.+'

ตัวเลือก SDK บางส่วนของ Facebook


เห็นด้วยอย่างสิ้นเชิง. ในกรณีของฉันฉันแค่ต้องการปุ่ม "เข้าสู่ระบบด้วย Facebook" และใช้ทั้ง sdk ของ Facebook ฉันได้แทนที่ด้วยfacebook-coreและfacebook-loginและข้อผิดพลาดได้หายไป
cleybertandre

0

สำหรับฉันการอัพเกรด Gradle ใช้งานได้ดูที่การอัปเดตที่เว็บไซต์ Android แล้วเพิ่มลงใน build.gradle ของคุณ (โครงการ) เช่นนี้

 dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha4'   
          ....
    }

จากนั้นซิงค์โครงการที่มีไฟล์ gradle และอาจเกิดขึ้นบางครั้งเพราะ java.exe (ในกรณีของฉัน) เพียงแค่บังคับให้ฆ่า java.exe จากตัวจัดการงานใน windows จากนั้นเรียกใช้โปรแกรมอีกครั้ง


0

ลองได้:

android{
    .
    .
    // to avoid DexIndexOverflowException
    dexOptions {
       jumboMode true
    }
}

หวังว่าจะช่วยใครซักคน ขอบคุณ


0

**

สำหรับ Unity Game Developers

**

หากใครมาที่นี่เพราะข้อผิดพลาดนี้ปรากฏขึ้นในโครงการ Unity ของพวกเขาไปที่ไฟล์ -> การตั้งค่าการสร้าง -> การตั้งค่าผู้เล่น -> ผู้เล่น ไปที่การตั้งค่าการเผยแพร่และภายใต้แท็บสร้างให้เปิดใช้งาน เส้นทางจะปรากฏภายใต้ข้อความนั้น ไปที่เส้นทางและเพิ่ม multiDexEnabled จริงเช่นนี้:

defaultConfig {
    minSdkVersion **MINSDKVERSION**
    targetSdkVersion **TARGETSDKVERSION**
    applicationId '**APPLICATIONID**'
    ndk {
        abiFilters **ABIFILTERS**
    }
    versionCode **VERSIONCODE**
    versionName '**VERSIONNAME**'
    multiDexEnabled true
}

-1

คุณสามารถเปิดใช้งาน "เรียกใช้ทันที" บน Android Studio เพื่อรับการสนับสนุนแบบหลายไฟล์


-2

ทำสิ่งนี้มันได้ผล:

defaultConfig {
    applicationId "com.example.maps"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
}

2
กรุณาอธิบายคำตอบของคุณ คำตอบที่ใช้รหัสไม่ได้มีไว้สำหรับ SO ขอบคุณ.
Gennadii Saprykin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.