Dex yürütülemiyor: yöntem kimliği [0, 0xffff] içinde değil: 65536


344

Daha önce dex erros'un çeşitli versiyonlarını gördüm, ama bu yeni. temiz / yeniden başlatma vb yardımcı olmaz. Kütüphane projeleri sağlam görünüyor ve bağımlılık doğru bir şekilde bağlantılı görünüyor.

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

veya

Cannot merge new index 65950 into a non-jumbo instruction

veya

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

tl; dr : Google'ın resmi çözümü sonunda burada!

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

Sadece küçük bir ipucu, dex-ing yaparken bellekte kalmayı önlemek için bunu yapmanız gerekecektir.

dexOptions {
        javaMaxHeapSize "4g"
}

Bunu daha az güvenilir bir şekilde düzeltebilecek bir jumbo modu da vardır:

dexOptions {
        jumboMode true
}

Güncelleme: Uygulamanız şişmansa ve ana uygulamanızda çok fazla yönteminiz varsa, uygulamanızı yeniden düzenlemeniz gerekebilir.

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


1
Currient cihazınızda aviable olmayan bir api kullanıyor musunuz?
Mar13'te rekor

Orada, çünkü başka bir proje aynı API sürümünü hedefleyen iyi bir yapı oluşturuyor.
Edison

Yani bir noktada kullanılabilir olmayan bir API kullanıyorsunuz? Kullanılamıyorsa if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)bu işlevi çağırmamanız gibi bir satırla kontrol ediyor musunuz ?
Mar13'te rekor

Evet yaptım. Proje daha önce iyi yapılmıştı. Ayrıca, hattı kaçırmış olsam bile, bu bir çalışma zamanı hatası olmalıdır.
Edison

Muhtemelen bağımlılıklardan biri berbat durumda. (şu anda maven + project lib'in bir karışımını yapıyor)
Edison

Yanıtlar:


379

Güncelleme 3 (03.11.2014)
Google nihayet resmi açıklama yayınladı .


Güncelleme 2 (31.10.2014)
Android için Gradle eklentisi v0.14.0 multi-dex desteği ekliyor . Etkinleştirmek için build.gradle içinde bildirmeniz yeterlidir :

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

Uygulamanız 5.0'dan önce Android'i destekliyorsa (yani, minSdkVersion20 veya daha düşükse ), uygulamayı ClassLoader'ı dinamik olarak yamalamanız gerekir , böylece ikincil dexes'ten sınıfları yükleyebilir. Neyse ki, bunu sizin için yapan bir kütüphane var. Uygulamanızın bağımlılıklarına ekleyin:

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

ClassLoader düzeltme eki kodunu en kısa zamanda aramanız gerekir. MultiDexApplicationsınıfın belgeleri bunu yapmanın üç yolunu önerir (bunlardan birini, sizin için en uygun olanını seçin):

1 - MultiDexApplicationSınıfı AndroidManifest.xml dosyasında uygulama olarak bildirin :

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

2 - ApplicationSınıfınızın MultiDexApplication sınıfını genişletmesini sağlayın :

public class MyApplication extends MultiDexApplication { .. }

3 - Çağrı MultiDex#installsenin dan Application#attachBaseContextyöntemle:

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

Güncelleme 1 ( 17/10/2014 ):
Beklendiği gibi, multidex desteği Android Destek Kitaplığı'nın 21. revizyonunda gönderilir. Android-support-multidex.jar dosyasını / sdk / extras / android / support / multidex / library / libs klasöründe bulabilirsiniz.


Multi-dex desteği bu sorunu çözer. dx 1.8 zaten birkaç dex dosyası oluşturulmasına izin veriyor.
Android L, multi-dex'i yerel olarak destekleyecek ve destek kitaplığının bir sonraki revizyonu, API 4'e eski sürümleri kapsayacaktır.

Bu ifade edildi bu Anwar Ghuloum tarafından Android Geliştiricileri Kulis podcast bölüm. Ben ettik Transkript yayınlanmıştır ilgili kısmın (ve genel çoklu dex açıklama).


2
blog yazısı bir tasarruf! : D
nadavfima

39
Tutulma kullanıcıları için bir şey var mı?
Muhammad Babar

52
@MuhammadBabar Eclipse kullanıcıları için Android stüdyosu var.
VipulKumar

2
@MohammedAli Elbette, yapabiliyorsanız kullanmaktan kaçının. Ancak uygulamanızda gerçekten çok fazla yönteminiz varsa ve bahsettiğiniz gibi tüm hileleri zaten denediyseniz ne yapmalısınız? Yapım süresi ile ilgili olarak - bunun için, en azından geliştirme yapıları için bir çözüm var - cevabımı buraya bakın: stackoverflow.com/a/30799491/1233652
Alex Lipov

2
Android için Qt'de, Facebook + Twitter'ın SDK'larını bir araya getirirken, multidex desteğini etkinleştirdikten sonra bile uygulama için çalışma zamanında sorunlar yaşıyordum (özellikle bu bir hata bana kabus verdi:) java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt5.android.QtActivityDelegate" on path: DexPathList[[],nativeLibraryDirectories=[/vendor/lib, /system/lib]]. Benim hatam, 5.0'dan önce Android desteği için ek adımlar uygulamadığım oldu. Bununla birlikte, 3. seçenek bunu çözdü ve daha fazla sorunum olmadı ClassNotFoundException. Teşekkürler, @Alex Lipov!
soymak

78

Daha önce de belirtildiği gibi, projenizde ve kütüphanelerinizde çok fazla yöntem (65k'dan fazla) var.

Sorunu Önleyin: Play Hizmetleri 6.5+ ve support-v4 24.2+ ile yöntem sayısını azaltın

Google Play hizmetleri çoğu zaman 20k + yöntemleriyle "israf" yöntemlerindeki ana şüphelilerden biridir . Google Play hizmetleri sürüm 6.5 veya üzeri, Google Play hizmetlerini uygulamanıza bir dizi küçük istemci kitaplığı kullanarak dahil etmeniz mümkündür . Örneğin, yalnızca GCM'ye ve haritalara ihtiyacınız varsa yalnızca bu bağımlılıkları kullanmayı seçebilirsiniz:

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

Alt kütüphanelerin tam listesi ve sorumlulukları resmi google doc'de bulunabilir .

Güncelleme : Destek Kütüphanesi v4 v24.2.0'dan bu yana aşağıdaki modüllere ayrılmıştır:

support-compat, support-core-utils, support-core-ui, support-media-compatVesupport-fragment

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

Bununla birlikte, kullanırsanız support-fragment, diğer tüm modüllere bağımlılıkları olacağını unutmayın (yani kullanırsanız android.support.v4.app.Fragmentfaydası olmaz)

Burada support-v4 lib için resmi sürüm notlarına bakın


MultiDexing'i etkinleştir

Lollipop (yani 21+ yapı araçları) olduğundan, kullanımı çok kolaydır. Yaklaşım uygulamanız için birden fazla dex dosyası oluşturmak için dex dosyası başına 65k yöntem sorunu etrafında çalışmaktır. Gradle derleme dosyanıza aşağıdakileri ekleyin ( bu, 65.000'den fazla yöntem içeren uygulamalarda resmi google doc'dan alınır ):

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

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

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

İkinci adım, Uygulama sınıfınızı hazırlamak veya Uygulamayı genişletmiyorsanız MultiDexApplicationAndroid Manifest'inizdeki kullanımı kullanın :

Bunu Application.java'nıza ekleyin

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

veya mutlidex lib'den sağlanan uygulamayı kullanın

<?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 ile OutOfMemory'yi önleyin

Daha fazla ipucu olarak, OutOfMemoryoluşturma aşamasında istisnalarla karşılaşırsanız, yığını genişletebilirsiniz.

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

bu da öbeği 4 gigabayta ayarlayacaktır.

Dex yığın bellek sorunu hakkında daha fazla bilgi için bu soruya bakın.


Sorunun kaynağını analiz edin

Yöntemlerin kaynağını analiz etmek için https://github.com/KeepSafe/dexcount-gradle-plugin dereceli eklentisi , ör.

.\gradlew app:dependencies

Android'de yöntem sayısı hakkında daha fazla bilgi için bu cevaba ve soruya bakın


Play Services 6.5+ çözümünü kullandım ve mükemmel çalıştı. İnanılmaz kullanışlı ipucu. Çok teşekkürler!
Hoang Nguyen Huu

Yapabilseydim daha fazla oy verirdim - bu sorunu çözmediğimiz diğer tüm Play Hizmetleri öğelerini kesmek, bina yaparken olumsuz performans etkileri olan multi-dex'e başvurmak zorunda kalmadan.
Sean Barbeau

1
Gözlerimde gözyaşları ile senden çok daha fazla. Beni kurtardın
uykusuzluk

GCM için istemci kitaplığı kullandım, çünkü oyun hizmetinden sadece gcm hizmeti kullanıyorum, şimdi bu sorunumu düzeltti. Teşekkürler! zamanımı kurtarmak için.
Ankit

57

Projeniz çok büyük. Çok fazla yönteminiz var. Uygulama başına sadece 65536 yöntem olabilir. buraya bakın https://code.google.com/p/android/issues/detail?id=7147#c6


Anlıyorum. Bu proje için birçok bağımlılığım var. Ben maven kullanmaya taşınmadan önce iyi inşa, belki maven gereksiz bağımlılıklar ekledi. İki kez kontrol eder.
Edison

5
Daha açık olmak gerekirse, Dalvik yürütülebilir (dex) dosyası başına yalnızca 65.536 yöntem olabilir. Ve bir uygulama (APK), özel yükleme gibi şeyleri içeren birden fazla dex dosyasına sahip olabilir.
Dennis Sheil

7
Android için gerçekten utanç verici bir hata! Her neyse, bence, ben yalanlarda olan ve kullanılmayan Jar kaldırdım ve uygulama derlendi
David

Projemi temizleme zamanı: /
Decoy

1
Hızlı bir düzeltme, Proguard'ı hata ayıklama yapılarıyla kullanmak olacaktır
aleb

12

Gradle kullanırsanız aşağıdaki kod yardımcı olur. 65 bin eşiğinin altına dönmek için gereksiz Google hizmetlerini (bunları kullandığınızı varsayarak) kolayca kaldırmanıza olanak tanır. Bu gönderinin tüm kredileri: https://gist.github.com/dmarcato/d7c91b94214acd936e42

Edit 2014-10-22 : Yukarıda atıfta bulunulan özde çok ilginç bir tartışma oldu. TLDR? şuna bir bak: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Bu kodu build.gradle dosyanızın altına yapıştırın ve ihtiyacınız olmayan google hizmetleri listesini ayarlayın:

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

Sevdim! Google gibi şirketler paketleri şişirmeye devam ederken def gerekiyor.
Edison

1
Güzel - bu iş yerinde yaptı. Hiçbir güçlük ve endişe!
slott

Not: Bu, Android Studio'daki Android SDK'mdaki google oyun hizmetleri kavanozlarını sildi! Kötü bir fikir çünkü orijinal kavanozlara geri dönmek kolay değil. Yazar, derleme dizinindeki kavanozları değiştirmek için komut dosyasını değiştirmelidir.
inder

@inder: Bu problemim yoktu. Ancak, cleanhariç tuttuğum maymunlarla her seferinde yapmak zorunda kaldım (analitiği kullanıyoruz).
JohnnyLambada

nasıl sürüm derlemeleri dışında tutmak için?
user1324936

6

Custom_rules.xml yapı komut dosyası ve birkaç satır kod kullanarak bu sorunu çözen örnek bir proje paylaştım.

Kendi projemde kullandım ve 1M + cihazlarda kusursuz çalışıyor (android-8'den son android-19'a kadar). Umarım yardımcı olur.

https://github.com/mmin18/Dex65536


1
Senaryolar için teşekkürler. ART'a dikkat etmelisin. Cihaz ikincil olanları değil, yalnızca varsayılan dex'inizi dönüştürebilir. Koruyucu çözeltiler tercih edilmelidir.
Edison

2
Eclipse içine projeler almak ve çalıştırmak zaman hata verir. Msgstr "Dex: yöntem kimliği yürütülemiyor [0, 0xffff]: 65536'da değil". Projenin kullanımını açıklayabilir misiniz
Karacago

6

Aynı sorunla karşılaştı ve bağımlılıklar bölümündeki build.gradle dosyamı düzenleyerek çözerek:

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

Ve yerine koymak:

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

Mükemmel! Sadece Google Drive API'sını kullanıyorum ve bu işe yarıyor.
vedavis

5

Build.gradle içinde aşağıdaki kodu eklemeyi deneyin, benim için çalıştı -

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}

2

Bunun için mükemmel çözüm Proguard ile çalışmak olacaktır. Yorumda belirtildiği gibi aleb. Dex dosyasının boyutunu yarı yarıya azaltacaktır.


1
Özellikle büyük bir google oyun hizmetleri kavanozu ile özellikle anlaştı * (18k yöntem kendi başına)
Edison

2

Android Studio'yu kullanarak sorunu (dex dosya referansları) analiz edebilirsiniz:

Yapı -> APK'yı Analiz Et ..

Sonuç panelinde classes.dex dosyasına tıklayın

Ve göreceksiniz:

resim açıklamasını buraya girin


0

kepçe + koruma çözümü:

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

0

Libs klasöründen bir jar dosyasını kaldırın ve başka bir klasöre kopyalayın ve _Proje Özellikleri> Java Oluşturma Yolunu Seçin, Kütüphaneleri Seçin, Harici Kavanoz Ekle'yi seçin, Projenize Kaldırılan kavanozu seçin, Kaydet'i tıklayın. Libs klasörü yerine kütüphane. Şimdi temiz ve Projenizi çalıştırın. MultDex için herhangi bir kod eklemenize gerek yoktur. Benim için işe yaradı.


0

Bugün aynı sorunla karşı karşıya kaldım.

ANDROID STUDIO için ... Anında Çalıştırmayı Etkinleştir

Dosya-> Tercihler-> Derleme, Yürütme, Dağıtım-> Anında Çalıştırma-> Anında çalışmayı anında değiştirme için etkinleştir seçeneğini işaretleyin ...

Umarım yardımcı olur


1
Bu benim için çalıştı - Çalışmayı Etkinleştir'i devre dışı bıraktım, Uygula'yı tıkladım, yeniden etkinleştirdim ve tekrar çalıştı.
MrBigglesworth
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.