diff --git a/example/app/libs/fat-aar-final.aar b/example/app/libs/fat-aar-final.aar index b23a3154..ef1d9582 100644 Binary files a/example/app/libs/fat-aar-final.aar and b/example/app/libs/fat-aar-final.aar differ diff --git a/example/gradle.properties b/example/gradle.properties index d015431a..287a7372 100644 --- a/example/gradle.properties +++ b/example/gradle.properties @@ -1,2 +1,3 @@ android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true +android.disableResourceValidation=true \ No newline at end of file diff --git a/example/lib-aar/src/main/res/values/attrs.xml b/example/lib-aar/src/main/res/values/attrs.xml new file mode 100644 index 00000000..76ffaf26 --- /dev/null +++ b/example/lib-aar/src/main/res/values/attrs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/example/lib-aar2/src/main/res/values/attrs.xml b/example/lib-aar2/src/main/res/values/attrs.xml new file mode 100644 index 00000000..29c51ff0 --- /dev/null +++ b/example/lib-aar2/src/main/res/values/attrs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/example/lib-main/build.gradle b/example/lib-main/build.gradle index 28ba820b..bb96fd17 100644 --- a/example/lib-main/build.gradle +++ b/example/lib-main/build.gradle @@ -71,6 +71,8 @@ fataar { * @since 1.3.0 */ transitive = true + + formatDeclareStyleable = true } dependencies { diff --git a/source/build.gradle b/source/build.gradle index 913630b5..c2d62e06 100644 --- a/source/build.gradle +++ b/source/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'groovy' -apply from: "./upload.gradle" +//apply from: "./upload.gradle" buildscript { repositories { @@ -19,4 +19,5 @@ dependencies { implementation localGroovy() implementation "org.javassist:javassist:3.27.0-GA" implementation 'com.android.tools.build:gradle:4.2.0' + implementation "org.dom4j:dom4j:2.1.3" } diff --git a/source/src/main/groovy/com/kezong/fataar/FatAarExtension.groovy b/source/src/main/groovy/com/kezong/fataar/FatAarExtension.groovy index 00e25716..005bb7cf 100644 --- a/source/src/main/groovy/com/kezong/fataar/FatAarExtension.groovy +++ b/source/src/main/groovy/com/kezong/fataar/FatAarExtension.groovy @@ -25,4 +25,6 @@ class FatAarExtension { * @since 1.3.0 */ boolean transitive = false + + boolean formatDeclareStyleable = false } diff --git a/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy b/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy index 9de20f25..06a68ef7 100644 --- a/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy +++ b/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy @@ -39,6 +39,7 @@ class FatAarPlugin implements Plugin { project.afterEvaluate { doAfterEvaluate() } + ValuesHelper.attach(project) } private registerTransform() { diff --git a/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy b/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy index 63d71eda..fafbd627 100755 --- a/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy +++ b/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy @@ -169,6 +169,13 @@ class VariantProcessor { it.destinationDir = aarOutputFile.getParentFile() } + if (mProject.fataar.formatDeclareStyleable) { + doFirst { + FatUtils.logAnytime("Extension formatDeclareStyleable enable!") + ValuesHelper.splitValuesXmlRepeatAttr(reBundleDir) + } + } + doLast { FatUtils.logAnytime(" target: ${aarOutputFile.absolutePath} [${FatUtils.formatDataSize(aarOutputFile.size())}]") } diff --git a/source/src/main/java/com/kezong/fataar/StyleAttr.java b/source/src/main/java/com/kezong/fataar/StyleAttr.java new file mode 100644 index 00000000..2d525f67 --- /dev/null +++ b/source/src/main/java/com/kezong/fataar/StyleAttr.java @@ -0,0 +1,28 @@ +package com.kezong.fataar; + +public class StyleAttr { + public StyleAttr(String name_, String format_) { + name = name_; + format = format_; + } + + public static final String ATTR_NAME = "name"; + public static final String ATTR_FORMAT = "format"; + public String name = ""; + public String format = ""; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + StyleAttr styleAttr = (StyleAttr) o; + return name.equals(styleAttr.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + +} \ No newline at end of file diff --git a/source/src/main/java/com/kezong/fataar/ValuesHelper.java b/source/src/main/java/com/kezong/fataar/ValuesHelper.java new file mode 100644 index 00000000..0e8e1e32 --- /dev/null +++ b/source/src/main/java/com/kezong/fataar/ValuesHelper.java @@ -0,0 +1,120 @@ +package com.kezong.fataar; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; +import org.gradle.api.Project; + + +public class ValuesHelper { + private static Project mProject; + private static final String ELE_ATTR = "attr"; + private static final String ELE_DECLARE_STYLEABLE = "declare-styleable"; + + public static void attach(Project project) { + // fix: org.xml.sax.SAXNotRecognizedException: unrecognized feature http://xml.org/sax/features/external-general-entities + System.setProperty("javax.xml.parsers.SAXParserFactory", + "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); + mProject = project; + project.getLogger().info("attach Values Helper"); + } + + public static void splitValuesXmlRepeatAttr(File pkgFile) { + + final File valueXml = new File(pkgFile, "res/values/values.xml"); + if (!valueXml.exists()) { + mProject.getLogger().info("ValuesHelper: value xml doesn't exist..."); + return; + } + try { + formatRepeatAttr(valueXml); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void formatRepeatAttr(final File file) { + try { + mProject.getLogger() + .info("ValuesHelper: deleteDuplicateAttr : " + file.getAbsolutePath()); + + SAXReader xmlReader = new SAXReader(); + + Document doc = xmlReader.read(file); + + final Element rootEle = doc.getRootElement(); + + if (rootEle == null) { + return; + } + List rootAttr = rootEle.elements(ELE_ATTR); + List styleableElements = rootEle.elements(ELE_DECLARE_STYLEABLE); + + final Set repeatStyleAttr = new HashSet<>(); + final Set styleAttrs = new HashSet<>(); + + //先查找根节点 attrs = declareStyle.elements(ELE_ATTR); + for (Element attr : attrs) { + StyleAttr styleAttr = getStyleAttr(attr); + if (styleAttr != null) { + if (styleAttrs.contains(styleAttr)) { + repeatStyleAttr.add(styleAttr); + } else { + styleAttrs.add(styleAttr); + } + if (repeatStyleAttr.contains(styleAttr)) { + Attribute format = attr.attribute(StyleAttr.ATTR_FORMAT); + attr.remove(format); + } + } + } + } + + + XMLWriter writer = new XMLWriter(new FileOutputStream(file)); + writer.write(doc); + writer.close(); + + } catch (Exception e) { + mProject.getLogger() + .info("ValuesHelper: exclude repeat attr failed : " + e.getMessage()); + e.printStackTrace(); + } + + } + + private static StyleAttr getStyleAttr(Element element) { + Attribute name = element.attribute(StyleAttr.ATTR_NAME); + Attribute format = element.attribute(StyleAttr.ATTR_FORMAT); + if (name != null && format != null) { + return new StyleAttr(name.getValue(), format.getValue()); + } + return null; + } +}