Số lượng tham chiếu phương thức trong tệp .dex không thể vượt quá 64k API 17


154

Tôi đang xây dựng một ứng dụng với Thư viện SugarORM nhưng khi tôi cố gắng xây dựng dự án cho API 17 (không kiểm tra cho người khác) thì nó hiển thị lỗi xây dựng.

    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

Nhưng khi tôi xây dựng dự án này cho Android v5.0 trở lên, nó hoạt động tốt. Nếu tôi loại bỏ phụ thuộc lớp SugarORM, nó hoạt động tốt cho cả hai thiết bị v4.2.2 và v5.0.



hãy thử sử dụng Proguard liên kết này android-arsenal.com/details/1/337 quy định cụ thể sử dụng SugarORM với Proguard
Shaan_B

19
Chỉ cần có được điều này sau khi nâng cấp lên api 23. Đơn giản là không thể làm việc hiệu quả với Android. Mỗi sdk phá vỡ mọi thứ. Mỗi bản cập nhật để AS phá vỡ mọi thứ. Thông báo lỗi không thể sử dụng. NHƯ bị hỏng. Rác, rác, rác.
RunLoop

1
@RunLoop đừng mất hy vọng .... Tôi thấy rằng Android là nền tảng tốt nhất từng được phát triển .... Moch linh hoạt và mạnh mẽ .... Vì bạn sẽ nhúng tay vào mã hóa .... Sẽ ổn thôi .... Mỗi thông báo lỗi đều hữu ích. Nhưng cần phải hiểu các thông điệp
Sandeep Singh Rana

2
@Balaj Khan One or more of the answers is exemplary and worthy of an additional bounty.Just to the point and accurate answer.Tôi đề nghị câu trả lời hàng đầu (và được chấp nhận)!
Jon Goodwin

Câu trả lời:


331

Bạn có quá nhiều phương pháp. Chỉ có thể có 65536 phương thức cho dex .

Theo đề xuất, bạn có thể sử dụng hỗ trợ multidex .

Chỉ cần thêm các dòng này vào 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
}

Ngoài ra, bạn Manifestthêm MultiDexApplicationlớp từ thư viện hỗ trợ multidex vào phần tử ứng dụng

    <?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>

Nếu bạn đang sử dụng Applicationlớp của riêng mình , hãy thay đổi lớp cha từ Applicationthành MultiDexApplication.
Nếu bạn không thể làm điều đó, trong lớp Ứng dụng của bạn sẽ ghi đè attachBaseContextphương thức bằng:

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

Một giải pháp khác là cố gắng xóa mã không sử dụng bằng ProGuard - Định cấu hình cài đặt ProGuard cho ứng dụng của bạn để chạy ProGuard và đảm bảo bạn đã thu nhỏ kích hoạt cho các bản dựng phát hành.


1
@Override được bảo vệ void Đính kèmBaseContext (Ngữ cảnh newBase) {super.attachBaseContext (newBase); MultiDex.install (cái này); } cũng ghi đè
Sandeep Singh Rana

1
Cmd-click MultiDexApplication, tôi thấy tệp. Class được dịch ngược đã thực hiện chính xác phần ghi đè AttachBaseContext () mà bạn mô tả. Vì vậy, tôi sẽ không cần phải ghi đè lên một lần nữa tôi đoán ..
Mete

4
Điều gì xảy ra nếu tôi không có quá nhiều phương pháp. Tôi không có nhiều phương pháp trên ứng dụng của mình. Tôi tin rằng nó thậm chí không đạt được điều đó.
Chiến tranh neon

6
Tôi chỉ thực hiện hai phần này: "multiDexEnables true" và biên dịch 'com.android.support:multidex:1.0.0', trong tệp build.grandle của tôi. Tôi không phải thay đổi bất cứ điều gì trong tệp kê khai của mình cũng như không làm những điều khác mà bạn đã đề cập về ghi đè tệp đính kèmBaseContext, v.v. Nhưng giải pháp của bạn đã khắc phục vấn đề cho tôi! Cảm ơn.
Jaime Montoya

2
@NeonWarge Có lẽ là do sự phụ thuộc của bạn. Có lẽ, bạn đã bao gồm toàn bộ Dịch vụ Google Play? Kiểm tra câu trả lời
mr5

131

Trong 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
    }

Đặt cái này bên trong defaultConfig của bạn:

multiDexEnabled true 

nó làm việc cho tôi


3
Cái này chỉ dành cho Lollipop hay cao hơn phải không?
Vic Torious

1
Nó làm cho việc xây dựng thành công, nhưng ứng dụng gặp sự cố sau khi khởi chạy.
Vasanth

18

Tôi nhận được thông báo lỗi này vì trong khi mã hóa dự án tự động cập nhật phiên bản biên dịch trong build.gradletệp của tôi :

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' }

Giải quyết nó bằng cách sửa phiên bản:

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
Tôi đang tạo một ứng dụng đơn giản, hoạt động tốt cho đến khi tôi thử làm theo hướng dẫn của Google Map Object. Đột nhiên tôi không thể biên dịch được nữa. Giải pháp này đã khắc phục điều đó cho tôi. Làm thế nào trên trái đất bạn đã làm việc đó ra?
maccaroo

4
Phương pháp này may mắn hoạt động vì các thư viện biên dịch mới có quá nhiều phương thức (vượt quá 65536) và các thư viện cũ thì không. Vì vậy, nó chỉ là một sửa chữa nhanh chóng, sớm hay muộn bạn nên sửa chữa bằng cách thêm hỗ trợ multidex như câu trả lời được chấp nhận.
Quan Nguyễn

15

Đây là những gì làm việc cho tôi:

Điều này xảy ra vì có quá nhiều phương pháp không sử dụng. Hầu hết các phương thức này đến từ các thư viện được bao gồm trong build.gradle của bạn

Sử dụng thu nhỏ và thu hẹp tài nguyên để sửa lỗi này bằng cách phân lớp và dọn sạch mã của bạn cùng một lúc.

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

12

Thay đổi cấp độ ứng dụng 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
    }

nó làm việc cho tôi


vâng, đây là một vấn đề cũ, nhưng đối với các phiên bản API cuối cùng, chúng tôi chỉ cần multiDexEnabledtùy chọn, không có phụ thuộc hoặc thay đổi tệp kê khai
Hpsaturn

11

Lỗi này cũng có thể xảy ra khi bạn tải tất cả các dịch vụ google play apis khi bạn chỉ sử dụng afew.

Như google đã nêu: "Trong các phiên bản dịch vụ Google Play trước 6.5, bạn phải biên dịch toàn bộ gói API vào ứng dụng của mình. Trong một số trường hợp, việc này khiến việc giữ số lượng phương thức trong ứng dụng của bạn trở nên khó khăn hơn (bao gồm cả API khung, phương thức thư viện và mã của riêng bạn) theo giới hạn 65.536.

Từ phiên bản 6.5, thay vào đó, bạn có thể biên dịch có chọn lọc API dịch vụ Google Play vào ứng dụng của mình. "

Ví dụ: khi ứng dụng của bạn cần bản đồ dịch vụ phát, bản đồ dịch vụ chơi. Bạn chỉ cần thêm hai apis trong tệp build.gradle của mình ở cấp ứng dụng như hiển thị bên dưới:

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

Thay vì:

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

Để có tài liệu đầy đủ và danh sách các dịch vụ google play apis bấm vào đây


9

Khi tham chiếu ứng dụng của bạn vượt quá 65.536 phương thức, bạn gặp phải lỗi xây dựng cho biết ứng dụng của bạn đã đạt đến giới hạn của kiến ​​trúc xây dựng Android

Hỗ trợ đa điểm trước Android 5.0

Các phiên bản của nền tảng trước Android 5.0 (API cấp 21) sử dụng thời gian chạy Dalvik để thực thi mã ứng dụng. Theo mặc định, Dalvik giới hạn các ứng dụng trong một tệp mã byte lớp.dex trên mỗi APK. Để vượt qua giới hạn này, bạn có thể thêm thư viện hỗ trợ multidex vào dự án của mình:

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

Hỗ trợ đa điểm cho Android 5.0 trở lên

Android 5.0 (API cấp 21) trở lên sử dụng thời gian chạy có tên ART, vốn hỗ trợ tải nhiều tệp DEX từ các tệp APK. Do đó, nếu minSdkVersion của bạn từ 21 trở lên, bạn không cần thư viện hỗ trợ multidex .

Tránh giới hạn 64K

  • Xóa mã không sử dụng bằng ProGuard - Cho phép thu nhỏ mã

Cấu hình multidex trong ứng dụng cho

Nếu minSdkVersion của bạn được đặt thành 21 hoặc cao hơn, tất cả những gì bạn cần làm là đặt multiDexEnables thành true trong tệp build.gradle cấp mô-đun của bạn

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

nếu minSdkVersion của bạn được đặt thành 20 hoặc thấp hơn, thì bạn phải sử dụng thư viện hỗ trợ multidex

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

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

Ghi đè lớp Ứng dụng, thay đổi nó để mở rộng MultiDexApplication (nếu có thể) như sau:

public class MyApplication extends MultiDexApplication { ... }

thêm vào tệp kê khai

<?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

Tôi đã phải đối mặt với cùng một vấn đề và để hỗ trợ multidex, bạn phải ghi nhớ minSdkVersion của ứng dụng của bạn. Nếu bạn đang sử dụng minSdkVersion 21 trở lên thì chỉ cần viết multiDexEnables đúng như thế này

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

Nó hoạt động với tôi và nếu bạn đang sử dụng minSdkVersion dưới 21 (dưới lolipop ) thì bạn phải làm thêm hai việc đơn giản

1. Đầu tiên thêm phụ thuộc này

biên dịch 'com.android.support:multidex:1.0.1'

trong bản dựng của bạn.

2. Cuối cùng và thứ hai thêm một dòng dưới đây vào ứng dụng của bạn trong bảng kê khai

android: 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 sau đó nó cũng sẽ hoạt động trong phiên bản thấp hơn .. :) Chúc mừng mã hóa


1

Chỉ là một nhận xét phụ, Trước khi thêm hỗ trợ cho multidex - hãy đảm bảo bạn không thêm các phụ thuộc không cần thiết.

Ví dụ: Trong hướng dẫn phân tích chính thức của Facebook

Họ nói rõ rằng bạn nên thêm phụ thuộc sau:

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

thực sự là toàn bộ FacebookSDK - vì vậy, nếu bạn cần ví dụ như Analytics, bạn cần thay thế nó bằng:

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

Tùy chọn SDK một phần của Facebook


Hoàn toàn đồng ý. Trong trường hợp của tôi chẳng hạn, tôi chỉ cần nút "đăng nhập bằng facebook" và đang sử dụng toàn bộ sdk facebook. Tôi đã thay thế nó bằng facebook-corefacebook-loginvà các lỗi đã biến mất.
cleybertandre

0

Đối với tôi Nâng cấp Gradle hoạt động. Xem cập nhật tại Trang web Android sau đó thêm nó vào build.gradle (Project) của bạn như thế này

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

sau đó đồng bộ hóa dự án với tệp gradle cộng với điều đó đôi khi có thể xảy ra do java.exe (trong trường hợp của tôi) chỉ cần hủy java.exe từ trình quản lý tác vụ trong windows rồi chạy lại chương trình


0

Cũng có thể thử điều này:

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

Hy vọng nó sẽ giúp được ai đó. Cảm ơn


0

**

Dành cho nhà phát triển trò chơi Unity

**

Nếu có ai đến đây vì lỗi này xuất hiện trong dự án Unity của họ, hãy chuyển đến Tệp-> Cài đặt bản dựng -> Cài đặt trình phát -> Trình phát. đi tới Cài đặt xuất bản và trong tab Xây dựng, bật "Mẫu lớp trình khởi chạy tùy chỉnh". một đường dẫn sẽ được hiển thị dưới văn bản đó. đi đến đường dẫn và thêm multiDexEnables đúng như thế này:

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

-1

bạn có thể bật "Chạy ngay lập tức" trên Android Studio để nhận được hỗ trợ đa chiều.


-2

Làm điều này, nó hoạt động:

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

2
Hãy giải thích câu trả lời của bạn. Các câu trả lời chỉ có mã không được khuyến khích trên SO. Cảm ơn bạn.
Gennadii Saprykin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.