以下是我build.gradle
的一部分:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
proguard-rules.pro
中没有任何内容,但我注意到生成了一个名为aapt_rules.txt
的文件,其中包含以下内容:
# view res/layout/abc_action_menu_item_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ActionMenuItemView { <init>(...); }
# view res/layout/abc_expanded_menu_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ExpandedMenuView { <init>(...); }
# view res/layout/abc_list_menu_item_layout.xml #generated:17
# view res/layout/abc_popup_menu_item_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ListMenuItemView { <init>(...); }
# view res/layout/abc_screen_toolbar.xml #generated:27
-keep class android.support.v7.internal.widget.ActionBarContainer { <init>(...); }
# view res/layout/abc_action_mode_bar.xml #generated:19
# view res/layout/abc_screen_toolbar.xml #generated:43
-keep class android.support.v7.internal.widget.ActionBarContextView { <init>(...); }
# view res/layout/abc_screen_toolbar.xml #generated:17
-keep class android.support.v7.internal.widget.ActionBarOverlayLayout { <init>(...); }
# view res/layout/abc_screen_content_include.xml #generated:19
-keep class android.support.v7.internal.widget.ContentFrameLayout { <init>(...); }
# view res/layout/abc_screen_simple_overlay_action_mode.xml #generated:23
-keep class android.support.v7.internal.widget.FitWindowsFrameLayout { <init>(...); }
# view res/layout/abc_screen_simple.xml #generated:17
-keep class android.support.v7.internal.widget.FitWindowsLinearLayout { <init>(...); }
# view v11/res/layout-v11/abc_screen_content_include.xml #generated:19
-keep class android.support.v7.internal.widget.NativeActionModeAwareLayout { <init>(...); }
# view res/layout/abc_action_mode_close_item_material.xml #generated:17
# view res/layout/abc_search_dropdown_item_icons_2line.xml #generated:27
# view res/layout/abc_search_dropdown_item_icons_2line.xml #generated:37
# view res/layout/abc_search_dropdown_item_icons_2line.xml #generated:48
# view res/layout/abc_search_view.xml #generated:116
# view res/layout/abc_search_view.xml #generated:128
# view res/layout/abc_search_view.xml #generated:38
# view res/layout/abc_search_view.xml #generated:60
# view res/layout/abc_search_view.xml #generated:97
-keep class android.support.v7.internal.widget.TintImageView { <init>(...); }
# view res/layout/abc_screen_simple.xml #generated:25
# view res/layout/abc_screen_simple_overlay_action_mode.xml #generated:32
-keep class android.support.v7.internal.widget.ViewStubCompat { <init>(...); }
# view res/layout/abc_action_menu_layout.xml #generated:17
-keep class android.support.v7.widget.ActionMenuView { <init>(...); }
# view res/layout/abc_activity_chooser_view.xml #generated:19
-keep class android.support.v7.widget.LinearLayoutCompat { <init>(...); }
# view res/layout/abc_search_view.xml #generated:78
-keep class android.support.v7.widget.SearchView$SearchAutoComplete { <init>(...); }
# view res/layout/abc_screen_toolbar.xml #generated:36
-keep class android.support.v7.widget.Toolbar { <init>(...); }
这显然保留了XML在支持库中使用的所有内容,即使根本不使用这些XML。并且再次保存的代码会使用shrinkResources true
来跳过所有资源。并且即使在支持库中没有使用任何内容,apk大小也会增加很多。其他图书馆也是如此。
那么有没有办法自定义aapt_rules.txt
或做类似的事情来删除那些未使用的代码和资源? (或者我需要在某个地方为此打开一个问题吗?)
答案 0 :(得分:1)
你可以看到aapt_rules.txt中有评论。除了每个保留的类之外,还有引用此类的相应布局文件。像那样:
# view res/layout/abc_list_menu_item_layout.xml #generated:17
# view res/layout/abc_popup_menu_item_layout.xml #generated:17
-keep class android.support.v7.internal.view.menu.ListMenuItemView { <init>(...); }
如果从构建过程中删除布局文件,则此行将消失,并且不会保留类。如果它没有在某个地方实际使用过,那么该课将会缩小。
那么我们如何从appcompat库中删除布局文件呢?我可以看到很少的选择,没有一个是完美的,但它们有效。
您只需从sdk \ extras \ android \ m2repository \ com \ android \ support \ appcompat-v7 \ version \ appcompat-v7-version.aar中删除文件即可。足够用于测试,对生产不利,因为在一些其他项目中可能使用相同的文件。我试过了它的确有效。
将具有相同名称的假文件放入项目中。名称冲突将发生。构建过程更喜欢您的假文件,因为项目文件具有更高的优先级。这样来自appcompat的文件将被忽略。我试过了它的确有效。
您可以制作一些花哨的gradle脚本,在构建过程中删除不需要的文件。我还没试过。
(shrinkResources选项没有帮助,因为在实际涉及shrinkResources之前会生成aapt_rules.txt。)
我希望有人会建议更好的方法来做到这一点
这样做之后,所有不需要的线都从aapt_rules.txt消失了。但它从最终的apk大小中节省了大约100 KB。对我来说没什么大不了的。但在你的情况下,结果可能会有所不同。
答案 1 :(得分:0)
如果您使用sbt-android
进行构建,则可以手动覆盖proguardConfig
,如下所示:
proguardConfig in Android := List("-dontobfuscate",
"-dontoptimize",
"-renamesourcefileattribute SourceFile",
"-keepattributes SourceFile,LineNumberTable",
"-verbose",
"-flattenpackagehierarchy",
"-dontusemixedcaseclassnames",
"-dontpreverify",
"-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*,!code/allocation/variable",
"-keepattributes *Annotation*",
"-dontnote android.annotation.**",
"-dontwarn android.support.**",
"-dontnote android.support.**",
"-dontnote scala.ScalaObject",
"-dontnote org.xml.sax.EntityResolver",
"-dontnote scala.concurrent.forkjoin.**",
"-dontwarn scala.beans.ScalaBeanInfo",
"-dontwarn scala.concurrent.**",
"-dontnote scala.reflect.**",
"-dontwarn scala.reflect.**",
"-dontwarn scala.sys.process.package$",
"-dontwarn **$$anonfun$*",
"-dontwarn scala.collection.immutable.RedBlack$Empty",
"-dontwarn scala.tools.**,plugintemplate.**",
"-keep class scala.collection.SeqLike { public java.lang.String toString(); }",
"-keep class android.support.v7.view.menu.ListMenuItemView { <init>(...); }",
...
)
答案 2 :(得分:-1)
以下定义是在getDefaultProguardFile('proguard-android.txt')中编写的,这是{android-sdks} / tools / proguard
目录中的默认proguard设置之一@RunWith(Arquillian.class)
public class BugTest {
private static final String CLEANUP_SCRIPT = "DROP SCHEMA IF EXISTS scheme1 CASCADE; "
+ "DROP SCHEMA IF EXISTS public CASCADE; "
+ "CREATE SCHEMA public AUTHORIZATION testdba;";
private static final String CREATE_SCRIPT = "CREATE SCHEMA scheme1; "
+ "CREATE TABLE scheme1.dbconfig ( propkey character varying NOT NULL, propvalue character varying NOT NULL, CONSTRAINT dbconfig_pkey PRIMARY KEY (propkey) ); "
+ "INSERT INTO scheme1.dbconfig VALUES ('initialized', true), ('version', 2);";
@Deployment
public static Archive<?> createDeployment() {
return ShrinkWrap.create(JavaArchive.class).addAsManifestResource("META-INF/beans.xml", "beans.xml")
.addAsManifestResource("META-INF/persistence.xml", "persistence.xml");
}
@PersistenceContext
private EntityManager em;
@Inject
private UserTransaction transaction;
@Before
public void setUp() throws Exception {
this.transaction.begin();
this.em.createNativeQuery(CLEANUP_SCRIPT).executeUpdate();
this.em.createNativeQuery(CREATE_SCRIPT).executeUpdate();
this.transaction.commit();
}
// since an exception gets thrown in the setUp() method, these are not called
// they are only needed because the exception gets thrown for more than
// four tests methods
@Test public void test1() { }
@Test public void test2() { }
@Test public void test3() { }
@Test public void test4() { }
@Test public void test5() { }
@Test public void test6() { }
@Test public void test7() { }
@Test public void test8() { }
}
所以,它保留了一切。
无用的代码可以通过另一个proguard文件{android-sdks} /tools/proguard/proguard-android-optimize.txt传递,它使用默认值5 转而优化代码( -optimizationpasses 5 )。