Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
joker committed Feb 7, 2019
0 parents commit 3795288
Show file tree
Hide file tree
Showing 58 changed files with 1,446 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/build
/captures
.externalNativeBuild
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
相关文章链接:[MainDex 优化记](https://mp.weixin.qq.com/s?__biz=MzUyMDg2ODgwOQ==&mid=2247483679&idx=1&sn=4520ae38f703ee3b2303c02b47a80639&chksm=f9e287b9ce950eafa38deb9d8bf898a3abcaa0234adcc08ad017d8fd89bfc612a8d6e6a1cefe&token=1165484979&lang=zh_CN#rd)

### 原理

此插件只作用于打包过程,编码过程无感知、无影响。

混淆之后将会产生一个包含应用中所有 class 的 jar,通过 ASM 扫描所有的类、类的方法、类的字段等一切可能会出现注解的地方,扫描到开发者配置的注解则将其删除;而如果当前类是注解类且是开发者所配置的类的话,该注解类将会被删除。

### 配置

thinAnnotation 默认删除**所有**的 SOURCE 时期注解,因为使用 SOURCE 时期注解的地方实际上会在 .java -> .class 过程中被擦除,所以所有的 SOURCE 注解类实际上都是无用类,例如 `android/support/design/widget/TabLayout$Mode` 类;thinAnnotation 默认删除了 `butterknife/` 包、 `android/support/annotation/` 包、`androidx/annotation/` 包的所有注解,原因是这些 CLASS 时期的类在运行时是无用的(除非特殊要求,CLASS 文件实际上也是可以全部删除的);开发者只需要配置想要删除的 CLASS 和 RUNTIME 时期的注解类,配置方式如下——

在 project/build.gradle 中:

```
buildscript {
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.github.jokermonn:thinAnnotation:0.0.2'
}
}
```

在 app/build.gradle 中:

```
apply plugin: 'thinAnnotation'
thinAnnotation {
// 是否开启插件
enable true
// 目标注解类的路径
shrinkClass = ['com/joker/maindexkeep/annotations/RuntimeAnn', 'com/joker/maindexkeep/annotations/Type']
// 目标包的路径
shrinkPackage = ['com/joker/maindexkeep/shrink']
}
```

日志在:`app/build/outputs/thinAnnotation` 路径下。

## 示例

以 butterknife 为例:

使用前:butterknife 包注解类存在,`@BindView` 等注解存在于 .class 文件中

![](http://imglf6.nosdn0.126.net/img/UnlRcDgySWkxbnZUbjBCSXdnUFoza3RCR0R1TGY0M0x6dkxwQksxaFdJS3FJUHhmT2FCK21RPT0.png?imageView&thumbnail=2490y1632&type=png&quality=96&stripmeta=0)

使用后:butterknife 包注解类全部删除,所有使用该注解的地方也都会被清除注解

![](http://imglf5.nosdn0.126.net/img/UnlRcDgySWkxbnZUbjBCSXdnUFozanN2dzFqaU4xREZZalNtc2JrSGw0WXNQWEQ5NlpQNUlnPT0.png?imageView&thumbnail=2238y1484&type=png&quality=96&stripmeta=0)
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
79 changes: 79 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
apply plugin: 'com.android.application'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'thinAnnotation'

android {
compileSdkVersion 28

defaultConfig {
applicationId "com.joker.maindexkeep"
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"

multiDexEnabled true
multiDexKeepProguard file('./maindex-rules.pro')
multiDexKeepFile file('./maindex-keep.txt')
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

dexOptions {
// keepRuntimeAnnotatedClasses false
}
}

thinAnnotation {
enable = true
shrinkClass = ['com/joker/maindexkeep/annotations/RuntimeAnn']
shrinkPackage = ['com/joker/maindexkeep/shrink']
}

dependencies {
implementation fileTree(dir: 'libs')
implementation 'com.squareup.wire:wire-runtime:2.2.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.google.guava:guava:27.0.1-android'
implementation "io.reactivex.rxjava2:rxjava:2.2.6"
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.android.support:exifinterface:28.0.0'
implementation 'com.github.bumptech.glide:glide:4.8.0'
implementation 'com.miguelcatalan:materialsearchview:1.0.1'
implementation 'com.sdsmdg.harjot:vectormaster:1.0.5'
implementation 'com.amap.api:3dmap:5.7.0'
implementation 'com.amap.api:location:3.5.0'
implementation 'com.amap.api:search:5.7.0'
implementation 'com.xyz.step:step:1.0.4'
implementation 'com.rengwuxian.materialedittext:library:2.1.4'
implementation 'info.hoang8f:fbutton:1.0.5'
implementation 'me.drakeet.materialdialog:library:1.3.1'
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
implementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.facebook.fresco:fresco:1.11.0'
implementation 'com.facebook.fresco:animated-gif:1.11.0'
implementation 'com.facebook.fresco:animated-webp:1.11.0'
implementation 'com.facebook.fresco:webpsupport:1.11.0'
implementation 'com.facebook.fresco:webpsupport:1.11.0'
implementation 'com.android.support:preference-v7:28.0.0'
implementation 'com.jakewharton:butterknife:8.4.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
}
Empty file added app/maindex-keep.txt
Empty file.
3 changes: 3 additions & 0 deletions app/maindex-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#-keep class com.joker.maindexkeep.model.AppReferencerence {
# public void test();
#}
85 changes: 85 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontshrink # 为了超过 66536
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-dontpreverify
-dontoptimize
-dontwarn
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-keepattributes Signature, InnerClasses, EnclosingMethod, *Annotation*
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn javax.annotation.**
-dontwarn kotlin.Unit
-dontwarn retrofit2.-KotlinExtensions
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
-keep class com.google.common.io.Resources {
public static <methods>;
}
-keep class com.google.common.collect.Lists {
public static ** reverse(**);
}
-keep class com.google.common.base.Charsets {
public static <fields>;
}

-keep class com.google.common.base.Joiner {
public static com.google.common.base.Joiner on(java.lang.String);
public ** join(...);
}

-keep class com.google.common.collect.MapMakerInternalMap$ReferenceEntry
-keep class com.google.common.cache.LocalCache$ReferenceEntry
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe
-dontwarn java.lang.ClassValue
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn javax.lang.model.element.Modifier

-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.common.internal.DoNotStrip *;
}
-keepclassmembers class * {
native <methods>;
}
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**

# app
-keep class com.joker.maindexkeep.model.AppReference {
public void test();
}
34 changes: 34 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.joker.maindexkeep">

<uses-sdk tools:overrideLibrary="com.miguelcatalan.materialsearchview, com.sdsmdg.harjot.vectormaster"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".App"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 添加了 process 属性所以将会被 keep 住 -->
<service
android:enabled="true"
android:exported="true"
android:name=".MultiProcessService"
android:process="t:second">
</service>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity"/>
</application>

</manifest>
19 changes: 19 additions & 0 deletions app/src/main/java/com/joker/maindexkeep/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.joker.maindexkeep;

import android.content.Context;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
import android.util.Log;
import com.joker.maindexkeep.model.AppReference;

public class App extends MultiDexApplication {
@Override protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
AppReference useless = new AppReference();
}

@Override public void onCreate() {
MultiDex.install(this);
super.onCreate();
}
}
23 changes: 23 additions & 0 deletions app/src/main/java/com/joker/maindexkeep/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.joker.maindexkeep;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.joker.maindexkeep.annotations.RuntimeAnn;

/**
* 方法/类被运行时注解所修饰,所以当前类将会被打入 maindex
*/
@RuntimeAnn
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@RuntimeAnn
void test() {

}
}
19 changes: 19 additions & 0 deletions app/src/main/java/com/joker/maindexkeep/MultiProcessService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.joker.maindexkeep;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

/**
* manifest 中有注释
*/
public class MultiProcessService extends Service {
public MultiProcessService() {
}

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
21 changes: 21 additions & 0 deletions app/src/main/java/com/joker/maindexkeep/SecondActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.joker.maindexkeep;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import butterknife.BindView;
import com.joker.maindexkeep.annotations.RuntimeAnn;

/**
* {@link BindView} 是运行时注解,所以当前类将会被打入 maindex
*/
public class SecondActivity extends AppCompatActivity {

@BindView(R.id.tv) TextView tv;

@Override @RuntimeAnn
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.joker.maindexkeep.annotations;

import android.support.annotation.StringDef;
import com.joker.maindexkeep.model.AnnotationWrapperReference;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import static com.joker.maindexkeep.annotations.AnnotationWrapper.Nothing.A;
import static com.joker.maindexkeep.annotations.AnnotationWrapper.Nothing.B;

/**
* 由于包含注解内部类,所以本身及本身引用的 {@link AnnotationWrapperReference}及 {@link AnnotationWrapperReference}
* 的引用类都将会被打入 maindex
*/
public class AnnotationWrapper {

public void test() {
AnnotationWrapperReference reference = new AnnotationWrapperReference();
}

@Retention(RetentionPolicy.SOURCE)
@StringDef({ A, B })
public @interface Nothing {
String A = "a";
String B = "b";
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/com/joker/maindexkeep/annotations/ClassAnn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.joker.maindexkeep.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.CLASS)
@Target({ ElementType.METHOD })
public @interface ClassAnn {
}

0 comments on commit 3795288

Please sign in to comment.