2013-04-17 5 views
17

여러 라이브러리 (Facebook, Google지도 v2 및 Quickblox 용)가 필요한 Android 앱을 개발 중이므로 그 중 많은 양의 오버플로가 발생합니다. 64 K 제한 :외부 항아리에서 Ant로 여러 Android dex 파일을 만들 수 없습니다.

나는 이러한 라이브러리의없이 할 수있는 것처럼
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 

, 나는 방법 제한 버그에 대한 해결책을 찾았다. Android Developers에서 인기있는 블로그 항목을 발견했습니다. 여기에는 소스 코드 부문이 권장됩니다. (내가 말하는 블로그 항목은 여기에서 찾을 수 있습니다 : http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html). 나는이 솔루션을 아무런 성공없이 시도해왔다.

내가 지금 가지고있는 문제는 가장 큰 코드가 내 앱 자체가 아니라 필수 라이브러리에 있기 때문에 앱에서로드해야하는 다른 덱스 파일 사이에 라이브러리를 분산시켜야한다는 것입니다. 개미의 내 지식은 매우 제한적이며, 내가 알고 싶은 것은 내가 덱스 내가 원하는 각 라이브러리에 복사하기 위해 내 build.xml 파일에 작성해야 무엇 :

  <!-- Primary dex to include my source code and some libraries. --> 
      <copy todir="${out.classes.absolute.dir}.1" > 
       <fileset dir="${out.classes.absolute.dir}" > 

       ... 

       </fileset> 
      </copy> 


      <!-- Secondary dex to include some other libraries. --> 
      <copy todir="${out.classes.absolute.dir}.2" > 
       <fileset dir="${out.classes.absolute.dir}" > 

       ... 

       </fileset> 
      </copy> 

이 어떤 도움이 정말 감사하겠습니다을 . 미리 감사드립니다, 친절하게 생각합니다!

+0

해결책을 찾았습니까? 나는 똑같은 문제가있다. – rupps

답변

0

ProGuard은 소스 코드 축소 도구이므로 응용 프로그램을 패키징 할 때 사용되지 않거나 중복되는 클래스는 모두 제거됩니다. 따라서 이러한 외부 JAR을 모두 사용하더라도 해당 클래스의 모든 클래스를 100 % 사용하지는 않으며 이러한 JAR 중 많은 클래스가 동일한 클래스를 가질 수 있습니다 (예 : Log4J 등).

Proguard is built into dex. 그러나 기본적으로 활성화되지는 않습니다. 릴리스 모드에서 ant를 실행해야하며 project.properties에서 행을 주석 처리해야 할 수도 있습니다.

대부분 ProGuard가 으로 끝나고 응용 프로그램에 사용되는 일부 클래스가 제거 될 수 있습니다.

-keep public class <full path to the class that you need> 

체크 아웃 안드로이드 ProGuard에서 문서 및 난독 화를 가능하게하는 (클래스와 메소드의) 크기를 줄일 수 있는지 : ProGuard에서, 당신은 class X not found 같은 오류를 얻을 컴파일 할 때 때, 당신은 그 클래스를 필요로하는 proguard.cfg에서 ProGuard를 구성하는 경우 APK에

6

내가 지금까지 들었던 가장 좋은 대답은 -dontobfuscate 플래그로 최적화 된 모드 (proguard-android-optimize.txt)로 ProGuard를 사용하여 최종 APK에서 사용하지 않는 클래스와 메소드를 제거합니다 (난독 화하지 않음) . 그런 다음 ProGuard mapping.txt를 사용하여 사용하는 라이브러리 JAR에서 사용되지 않는 클래스를 제거 할 수 있습니다 (이 작업을 수행하는 데 유용한 도구는 아님). 불행히도 ProGuard에는이 작업을 자동으로 수행하는 기능이 없다고 생각합니다.

ProGuard는 Run As -> Android Application을 수행 할 때가 아니라 Eclipse에서 내보내기를 실행할 때만 실행됩니다. 즉, 사용자 정의 빌드 프로세스를 사용하지 않는 한 디버그 빌드의 한계를 피하는 데 도움이되지 않습니다. ProGuard의 개발자는 상업용 형제 인 DexGuard을 사용할 것을 제안합니다.이 제품은 디버그 및 릴리스 빌드 모두에서 Eclipse에서 실행됩니다.

ProGuard를 사용하면 코드 크기가 줄어들고 코드를 인라이닝 (inlining)하여 성능이 향상되며 소스 코드도 혼란스럽게되므로 릴리스 빌드를 사용하는 것이 좋습니다. 최종 APK 테스트가 디버그 테스트와 크게 다를 수 있으므로 충분한 테스트를 수행해야합니다. 불행하게도 ProGuard만으로는 문제를 해결할 수 없었기 때문에 해결 방법으로 JAR 종속성 중 하나를 제거했습니다.우리의 가장 큰 라이브러리에 대한 방법의

dx --dex --output=temp.dex library.jar 
cat temp.dex | head -c 92 | tail -c 4 | hexdump -e '1/4 "%d\n"' 

예 번호 : 참고로

11222 guava-11.0.1.jar  
10452 aws-android-sdk-1.5.0-core.jar  
5761 org.restlet.jar  
5129 protobuf-java-2.4.1.jar  
2499 aws-android-sdk-1.5.0-s3.jar  
2024 ormlite-core-4.41.jar  
1145 gson-2.2.2.jar  
1716 google-http-client-1.11.0-beta.jar  

, 당신은 방법의 수를 확인할 수 있습니다

내가이 명령을 사용하여 내 의존 항아리에 방법의 수를 확인 dexdump (SDK build-tools 폴더에서 찾을 수 있습니다 (예 : 'Android Studio.app/sdk/build-tools/21.0.2/dexdump')를 사용하는 APK :

dexdump -f MyApp.apk | grep method_ids_size 
method_ids_size  : 64295 

YouTube 검색을 수행 할 때 구아바 만 사용했기 때문에 해당 종속성을 제거하고 더 많은 호흡 실을 제공하기가 쉬웠습니다.

업데이트

: 나는 큰 항아리 나는 트림을 원하는 특정 입력 JAR와 그 최종 JAR를 비교하는 JD-GUI를 사용하여 내 Proguard와 빌드 dex2jar 사용하는 것이었다에서 사용하지 않는 코드를 제거하는 가장 쉬운 방법을 발견했다. 그런 다음 Proguard가 제거한 최상위 패키지를 제거합니다. 이를 통해 aws-android-sdk-1.5.0-core.jar에서> 8000 개 이상의 메소드를 제거 할 수있었습니다.

+0

공유해 주셔서 감사합니다. jar 파일에서 원하지 않는 패키지를 제거하는 방법을 알고 싶습니까? jar 파일 자체는 바이너리 형식입니다. Java 파일 형식의 JD-GUI를 사용하여 이들을 디 컴파일하고 Jar로 다시 다시 컴파일합니까? –

+0

"jar"도구를 사용하여 분리 및 재 병설하십시오. –