source

dex를 실행할 수 없습니다: 메서드 ID가 [0, 0xffff]에 없습니다: 65536

factcode 2023. 10. 1. 22:01
반응형

dex를 실행할 수 없습니다: 메서드 ID가 [0, 0xffff]에 없습니다: 65536

이전에 다양한 버전의 덱스터 오류를 본 적이 있지만 이번 것은 새것입니다. 클린/재시작 등은 도움이 되지 않습니다.도서관 프로젝트는 온전한 것 같고 의존성은 올바르게 연결된 것 같습니다.

Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

아니면

Cannot merge new index 65950 into a non-jumbo instruction

아니면

java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

tl;dr: Google의 공식 솔루션이 드디어 나왔습니다!

http://developer.android.com/tools/building/multidex.html

작은 팁 하나만, 덱스를 할 때 메모리 부족을 방지하기 위해 이 작업을 수행해야 할 것입니다.

dexOptions {
        javaMaxHeapSize "4g"
}

신뢰성이 떨어지는 방식으로 이 문제를 해결할 수 있는 점보 모드도 있습니다.

dexOptions {
        jumboMode true
}

업데이트: 앱이 뚱뚱하고 메인 앱 안에 방법이 너무 많으면 앱을 다시 정렬해야 할 수도 있습니다.

http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html

3(11/3/2014)
구글은 마침내 공식적인 설명을 발표했습니다.


2(10/31/2014)
Android용 Gradle 플러그인 v0.14.0은 멀티덱스를 지원합니다.활성화하려면 build.gradle로 선언하기만 하면 됩니다.

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

이 5하는 경우(이 5.0이 Android 를를 하는 (, )minSdkVersion는 20 이하입니다. 또한 응용 프로그램 ClassLoader를 동적으로 패치해야 2차 덱스에서 클래스를 로드할 수 있습니다.다행히도 그렇게 해주는 도서관이 있습니다.앱의 종속성에 추가합니다.

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

가능한 빨리 ClassLoader 패치 코드를 호출해야 합니다.MultiDexApplication클래스 문서에서는 다음과 같은 세 가지 방법을 제시합니다(그 중에서 가장 편리한 방법을 선택하십시오).

- 1 - MultiDexApplicationAndroidManifest.xml의 응용 프로그램으로 클래스:

<?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">
        ...
    </application>
</manifest>

- 를 가져라 - Application클래스 확장 MultiDexApplication 클래스:

public class MyApplication extends MultiDexApplication { .. }

- 콜 3 - 콜 3MultiDex#installm에서Application#attachBaseContext방법:

public class MyApplication {
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        ....
    }
    ....
}

업데이트 1(10/17/2014):
예상대로 멀티덱스 지원은 Android Support Library 버전 21에서 제공됩니다./sdk/extra/android/support/multidex/library/libs 폴더에서 Android-support-multidex.jar를 찾을 수 있습니다.


다중 덱스 지원을 통해 이 문제가 해결됩니다. dx 1.8은 이미 여러 덱스 파일을 생성할 수 있습니다.
L은 지원 4. Android L은하며,를 API 4입니다로 할 예정입니다.

안와르 굴룸(Anwar Gulouum)이 안드로이드 개발자 백스테이지 팟캐스트 에피소드에서 언급했습니다.해당 부분에 대한 녹취록(및 일반적인 멀티덱스 설명)을 올렸습니다.

이미 언급한 바와 같이 프로젝트 및 라이브러리에 너무 많은 방법(65k 이상)이 있습니다.

문제 방지:Play Services 6.5+ 및 support-v4 24.2+로 메소드 수 감소

Google Play Services는 종종 20k 이상의 방법으로 "낭비"하는 방법을 사용하는 주요 용의자 중 하나입니다.Google Play Services 버전 6.5 이상에서는 다수의 소규모 클라이언트 라이브러리를 사용하여 Google Play Services를 응용프로그램에 포함할 수 있습니다.예를 들어 GCM과 지도만 필요한 경우 다음 종속성만 사용하도록 선택할 수 있습니다.

dependencies {
    compile 'com.google.android.gms:play-services-base:6.5.+'
    compile 'com.google.android.gms:play-services-maps:6.5.+'
}

하위 라이브러리의 전체 목록과 책임은 공식 구글 문서에서 확인할 수 있습니다.

업데이트: Support Library v4 v24.2.0 이후로 다음 모듈로 분리되었습니다.

support-compat,support-core-utils,support-core-ui,support-media-compat그리고.support-fragment

dependencies {
    compile 'com.android.support:support-fragment:24.2.+'
}

그러나 다음을 사용하는 경우 주의하십시오.support-fragment 를 (, 를) )에.android.support.v4.app.Fragment득이 없음)

support-v4 lib에 대한 공식 릴리스 정보를 참조하십시오.


다중 디싱 사용

롤리팝(일명 빌드 툴 21+)으로 매우 다루기 쉽습니다.접근 방식은 DEX 파일 문제당 65k 방법을 사용하여 앱에 여러 개의 DEX 파일을 생성하는 것입니다.그래들 빌드 파일에 다음을 추가합니다. (이 파일은 65k 이상의 메서드를 사용하는 응용 프로그램에 대한 공식 Google 문서에서 가져온 것입니다.)

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

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

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

두 프로그램 는 Application 하거나 Application을 합니다.MultiDexApplicationAndroid 매니페스트:

Application.java에 추가합니다.

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

또는 mutlidex lib에서 제공된 애플리케이션을 사용합니다.

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

MultiDex로 메모리 부족 방지

추가적인 팁으로, 만약 당신이 당신과 마주친다면.OutOfMemory다를 할 수 .

android {
    ...
    dexOptions {
        javaMaxHeapSize "4g"
    }
}

4기가바이트로 설정할 수 있습니다.

DEX 힙 메모리 문제에 대한 자세한 내용은 이 질문을 참조하십시오.


문제의 원인 분석

방법의 출처를 분석하기 위해 Gradle 플러그인 https://github.com/KeepSafe/dexcount-gradle-plugin 은 Gradle이 제공하는 종속성 트리와 함께 예를 들어 제공할 수 있습니다.

.\gradlew app:dependencies

Android의 메소드 수에 대한 자세한 내용은 이 답변 및 질문 참조하십시오.

당신의 프로젝트는 너무 큽니다.방법이 너무 많아요.응용 프로그램당 65536개의 메서드만 있을 수 있습니다.여기 https://code.google.com/p/android/issues/detail?id=7147#c6 를 참조하십시오.

그래들을 사용한다면 아래 코드가 도움이 됩니다.불필요한 Google 서비스를 쉽게 제거하여(사용 중인 것으로 가정) 65k 임계값 아래로 돌아갈 수 있습니다.이 게시물에 공을 돌립니다: https://gist.github.com/dmarcato/d7c91b94214acd936e42

편집 2014-10-22:위에서 언급한 요지에 대해 많은 흥미로운 논의가 있었습니다.TLDR? 이것 좀 보세요: https://gist.github.com/Takhion/10a37046b9e6d259bb31

build.gradle 파일 하단에 이 코드를 붙여넣고 필요 없는 Google 서비스 목록을 조정합니다.

def toCamelCase(String string) {
    String result = ""
    string.findAll("[^\\W]+") { String word ->
        result += word.capitalize()
    }
    return result
}

afterEvaluate { project ->
    Configuration runtimeConfiguration = project.configurations.getByName('compile')
    ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
    // Forces resolve of configuration
    ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion

    String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
    File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir

    Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") {
        inputs.files new File(playServiceRootFolder, "classes.jar")
        outputs.dir playServiceRootFolder
        description 'Strip useless packages from Google Play Services library to avoid reaching dex limit'

        doLast {
            copy {
                from(file(new File(playServiceRootFolder, "classes.jar")))
                into(file(playServiceRootFolder))
                rename { fileName ->
                    fileName = "classes_orig.jar"
                }
            }
            tasks.create(name: "stripPlayServices" + module.version, type: Jar) {
                destinationDir = playServiceRootFolder
                archiveName = "classes.jar"
                from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) {
                    exclude "com/google/ads/**"
                    exclude "com/google/android/gms/analytics/**"
                    exclude "com/google/android/gms/games/**"
                    exclude "com/google/android/gms/plus/**"
                    exclude "com/google/android/gms/drive/**"
                    exclude "com/google/android/gms/ads/**"
                }
            }.execute()
            delete file(new File(playServiceRootFolder, "classes_orig.jar"))
        }
    }

    project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task ->
        task.dependsOn stripPlayServices
    }
}

custom_rules.xml 빌드 스크립트와 몇 줄의 코드를 사용하여 이 문제를 해결하는 샘플 프로젝트를 공유했습니다.

저는 제 프로젝트에서 사용했는데 1M+ 기기에서 완벽하게 작동합니다(안드로이드-8부터 최신 안드로이드-19까지).도움이 되길 바랍니다.

https://github.com/mmin18/Dex65536

동일한 문제에 직면하여 종속성 섹션에서 build.gradle 파일을 편집하고 다음을 제거하여 해결했습니다.

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

그리고 그것을 다음과 같이 대체합니다.

compile 'com.google.android.gms:play-services-location:7.8.0'
compile 'com.google.android.gms:play-services-analytics:7.8.0' 

build.gradle에서 아래 코드를 추가해보세요. 나에게 효과가 있었습니다.

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}

이에 대한 완벽한 해결책은 댓글에서 언급된 대로 Proguard.와 함께 작업하는 것입니다.덱스 파일의 크기를 절반으로 줄일 것입니다.

Android Studio를 사용하여 문제(덱스 파일 참조)를 분석할 수 있습니다.

빌드 -> APK 분석..

결과 패널에서 classes.dex 파일을 클릭합니다.

그리고 알게 될 것입니다.

enter image description here

그라들 + 프로가드 용액:

afterEvaluate {
  tasks.each {
    if (it.name.startsWith('proguard')) {
        it.getInJarFilters().each { filter ->
            if (filter && filter['filter']) {
                filter['filter'] = filter['filter'] +
                        ',!.readme' +
                        ',!META-INF/LICENSE' +
                        ',!META-INF/LICENSE.txt' +
                        ',!META-INF/NOTICE' +
                        ',!META-INF/NOTICE.txt' +
                        ',!com/google/android/gms/ads/**' +
                        ',!com/google/android/gms/cast/**' +
                        ',!com/google/android/gms/games/**' +
                        ',!com/google/android/gms/drive/**' +
                        ',!com/google/android/gms/wallet/**' +
                        ',!com/google/android/gms/wearable/**' +
                        ',!com/google/android/gms/plus/**' +
                        ',!com/google/android/gms/topmanager/**'
            }
        }
    }
  }
}

Libs 폴더에서 일부 jar 파일을 제거하고 다른 폴더로 복사한 후 _Project Properties > Java 빌드 경로 선택, 라이브러리 선택, 외부 jar 추가, 프로젝트에 제거된 jar 선택, 저장을 클릭하면 Libs 폴더 대신 Referenceed Library 아래에 추가됩니다.이제 프로젝트를 정리하고 실행합니다.MultDex에는 Any code를 추가할 필요가 없습니다.저한테는 그냥 효과가 있었어요.

저는 오늘도 같은 문제에 직면해 있었습니다. 그 문제는 아래와 같습니다.

ANDRODY STUDIO의 경우...인스턴트 실행 사용

파일->환경설정->구축, 실행, 배포->인스턴트 실행-> 핫 스왑에 대해 인스턴트 실행 사용...

도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/15209831/unable-to-execute-dex-method-id-not-in-0-0xffff-65536

반응형