Android 바보 패키지 플러그인

6731 단어
https://github.com/TangXiaoLv/Android-Easy-MultiDex
주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?
원인:Gralde1.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에 문제가 있습니다.

좋은 웹페이지 즐겨찾기