Android 바보 패키지 플러그인
주1: 앞부분을 보기 싫으면 맨 아래 설정 부분으로 건너뛸 수 있습니다.주2: 이 플러그인은 DexKnifePlugin 1.5.2 최적화 개조를 바탕으로 한 것입니다.ceabie의 사심 없는 헌신에 감사드립니다.
구덩이를 메우는 길
갱1:65536, So easy!
원인: Dalvik의 invoke-kind 명령이 집중되었고method reference index는 16bits만 남겼으며 최대 65535가지 방법을 인용할 수 있습니다.참조=>안드로이드 65K 방법수 제한으로 인한 사고.
해결 방법:
dependencies {
compile 'com.android.support:MultiDex:1.0.1'
}
Application 상속, attachBaseContext 다시 쓰기
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
갱2: Too many classes in – main-dex-list, what?
원인: 위의 공식 하도급을 통해 원 Dex를 1 주 Dex 가도종 Dex로 나누었다.주 Dex는 4대 구성 요소, Application, Annotation, multidex 등과 필요한 직접적인 의존을 포함한다.우리의 방법 수가 이미 16W에 이르렀기 때문에, 수백 개의Activity가 모두 메인 Dex에 넣었고, 또 성공적으로 메인 Dex를 폭발시켰다.
해결:gradle
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = []
}
dx.additionalParameters += '--set-max-idx-number=48000'
}
}
참조=>Android Dex 패키지 여행
갱3:gradle 1.5.0 이후 이런 문법은 지원되지 않습니다. what the fuck?
원인:Gralde
1.5.0
이상은 (jacoco,progard,multi-dex)를Transform API로 통일적으로 옮겼지만 Transform API는 생각보다 간단하지 않았다. Google을 뒤져서Gradle1.5.0
이상의 패키지 플러그인을 호환하는 DexKnifePlugin을 찾았다.확장 => 이 Android 핫 픽스는Gradle Plugin1을 사용합니다.5 Nuwa 플러그인을 개조하는 것이 비교적 좋은 Transform API의 사용을 소개했다.갱4:NoClass Def Found Error,are you kiding me?
원인: 플러그인을 통해maindex에서 보존할 클래스를 수동으로 지정합니다. 패키지는 성공했지만,maindex의 클래스와 직접 인용 클래스는 수동으로 지정하기 어렵습니다.
해결 방법: 미국 그룹 안드로이드 DEX 자동 클러치 및 동적 로드 프로필은 클라스 의존을 자동으로 분석할 수 있는 스크립트를 작성하여 메인 Dex가 포함해야 할 모든 필요 의존을 계산한다.대본 쓰느라 못 뛰겠네.
구덩이 5: 사용자 정의 스크립트, read the fuck source!
문제1: 주요 Dex에 넣어야 하는 클래스는 무엇입니까?sdk\build-tools\platform-version\mainDexClasses 보기.rules는 주 Dex와 관련된 클래스에 Instrumentation, Application,Activity,Service,ContentProvider,BroadcastReceiver,BackupAgent의 모든 하위 클래스를 넣는 것을 발견했다.
문제2:gradle은 어디에서 주 Dex 의존도를 계산합니까?Gradle 컴파일 작업을 살펴보면 다음과 같은 3개의 컴파일 작업이 있습니다.
collect 작업을 실행하면build/multi-dex 디렉터리에서 단독으로
manifest_keep.txt
파일을 생성할 수 있습니다. 이 파일은 사실 상기 규칙 스캔AndroidManifest
을 통해 생성됩니다.manifest_keep.txt
보존된 것은 메인 Dex에 넣어야 하는 모든 종류입니다.아직 끝나지 않았습니다. 다음transformClassesWithMultidexlist
작업은 manifest_keep.txt
에 따라 필요 의존 목록maindexlist.txt
을 생성합니다. 이 안의 모든 종류가 주 Dex에 진정으로 들어갑니다.bingo, 지금 아주 잘 알고 있습니다. 우리는 manifest에 들어가는 것을 제어하기만 하면 됩니다.keep.txt의 클래스만 있으면 됩니다. 최종적으로 그 클래스의 의존 관계는 시스템이 우리를 도와 생성하면 됩니다. 안전하고 녹색이 믿을 만합니다!문제3:
maindexlist.txt
의 크기를 어디서 조절합니까?문제1은 생성manifest_keep.txt
의 규칙을 알고 있다. 대부분의 프로젝트에 있어 manifest_keep.txt
중 80%가 Activity이다. 사실 우리는 모든 Activity를 메인 Dex에 넣을 필요가 없다. 필요한 Activity만 보류하면 된다. 예를 들어 첫 페이지의 Activity, Laucher Activity, 환영 페이지의 Activity 등 시작할 때 필요한 Activity는 OK이다.다음 그림은Gradle의 작업 흐름: 출처: 안드로이드의Gradle을 깊이 이해하기
우리는 퀘스트 벡터맵을 완성한 후에 퀘스트를 수행하기 전에 훅 퀘스트를 실행하고 불필요한 activity를 필터하면 됩니다.Gradle 추가:
// dex Activity
def mainDexListActivity = ['WelcomeActivity', 'MainFunctionActivity']
afterEvaluate {
project.tasks.each { task ->
if (task.name.startsWith('collect') && task.name.endsWith('MultiDexComponents')) {
println "main-dex-filter: found task $task.name"
task.filter { name, attrs ->
String componentName = attrs.get('android:name')
if ('activity'.equals(name)) {
def result = mainDexListActivity.find {
componentName.endsWith("${it}")
}
return result != null
} else {
return true
}
}
}
}
}
갱6:주dex 여전히 시계 폭발,shit again!
사실 위의 스크립트는 주 Dex에 넣고 싶은
manifest_keep
과 maindexlist
를 성공적으로 선별했지만, 포장할 때 모든 종류를 주 Dex에 넣었다. (어이가 없다.)이럴 때DexKnifePlugin 플러그인과 함께 사용해야 합니다. 우선gradle에 상기 스크립트를 추가한 다음 플러그인을 사용할 때 설정 파일-split **.**
과 #-donot-use-suggest
를 추가합니다.DexKnifePlugin 플러그인의 운행 원리는 매우 간단합니다. Dex 작업을 생성하기 전에 먼저 자신의 프로필 (앞에서 우리가Gradle 스크립트를 통해 생성한 maindexlist
목록 포함) 을 읽고combined를 스캔합니다.jar (프로젝트의 모든.class 파일 포함) 은 사용자 정의maindexlist와 일치합니다.txt,build/multi-dex/maindexlist를 다시 바꿉니다.txt,build 실례.이렇게 하도급을 나눌 때 우리의 규칙에 따라 주 Dex가 생성됩니다.갱 7: ANR, 하하!
우리의 최저 API=16, 테스트에서 ANR 문제를 발견하지 못했기 때문에 당분간 경상첨화를 고려하지 않았기 때문에 이 문제는 비교적 잘 해결되었다.참조=>Android Dex 패키지 여행
Congratulation
축하합니다. 구덩이 채우기가 끝났습니다. 하지만 Gradle 스크립트와 플러그인 설정을 동시에 유지해야 합니다.그리하여Gradle 스크립트를 플러그인에 통합시켰습니다. 프로필 하나만 유지하면 됩니다.독자는 자신의 수요에 따라 분리 배치를 선택할 수 있고 통합 배치를 선택할 수 있다.이런 방식을 통해 우리는 주Dex의 방법수를 15000위안 정도로 유지하고, 이때부터 더 이상 방법수 문제를 걱정할 필요가 없다!!!
구성 섹션
첫 번째 단계: 프로젝트 루트 디렉터리로 리포 디렉터리 복사
2단계: 루트 디렉터리Gradle 추가
buildscript {
repositories {
maven {
url uri('repo')
}
}
dependencies {
classpath 'com.ceabie.dextools:gradle-dexknife-plugin:2.0.0'
}
}
세 번째 단계: 당신의 앱 모듈의build.gradle 플러그인 추가
apply plugin: 'com.ceabie.dexnkife'
4단계: 당신의 앱 모듈 디렉터리에 dexknife를 새로 만듭니다.txt 및 사용자 정의 설정
#
#----------- Dex -----------
# ,Activity ( -just activity ), Activity
-just activity com.ceabie.demo.MainActivity
#----------- -----------
# maindex , -keep , . ,
# .
#-keep android.support.v7.app.AppCompatDialogFragment.class
# dex .
#android.support.v?.**
# Dex
-split **.**
# Android gradle miandex .( )
#-donot-use-suggest
# dex , dex id 65536.( )
#-auto-maindex
# miandex .
#-log-mainlist
5단계:defaultConfig 또는buildTypes에서multiDexEnabled true를 열지 않으면 작동하지 않습니다
알려진 오류
오류 1:
Error:Execution failed for task ':Toon:transformClassesWithDexForDebug'.> java.lang.NullPointerException (no error message)
이 오류가 발생하면Gradle 버전을 한 번 바꾸면 OK입니다. 예를 들어 1.5.0
오류 2:
Unsupported major.minor version 52.0
JDK 1.8로 업그레이드
오류 3:
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
> DexKnife Warnning: Main dex is EMPTY ! Check your config and project!
gradle을 1.5.0으로 자르면 현재gradle 2.1.2에 문제가 있습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.