Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format <declare-styleable/> #392

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified example/app/libs/fat-aar-final.aar
Binary file not shown.
3 changes: 2 additions & 1 deletion example/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
android.useAndroidX=true
android.enableJetifier=true
android.enableJetifier=true
android.disableResourceValidation=true
7 changes: 7 additions & 0 deletions example/lib-aar/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DeclareStyleableDefault">
<attr format="color" name="exampleTextColor"/>
<attr format="color" name="exampleBackground"/>
</declare-styleable>
</resources>
7 changes: 7 additions & 0 deletions example/lib-aar2/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DeclareStyleableNew">
<attr format="color" name="exampleTextColor"/>
<attr format="color" name="exampleTintTitle"/>
</declare-styleable>
</resources>
2 changes: 2 additions & 0 deletions example/lib-main/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ fataar {
* @since 1.3.0
*/
transitive = true

formatDeclareStyleable = true
}

dependencies {
Expand Down
3 changes: 2 additions & 1 deletion source/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apply plugin: 'groovy'
apply from: "./upload.gradle"
//apply from: "./upload.gradle"

buildscript {
repositories {
Expand All @@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ class FatAarExtension {
* @since 1.3.0
*/
boolean transitive = false

boolean formatDeclareStyleable = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class FatAarPlugin implements Plugin<Project> {
project.afterEvaluate {
doAfterEvaluate()
}
ValuesHelper.attach(project)
}

private registerTransform() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())}]")
}
Expand Down
28 changes: 28 additions & 0 deletions source/src/main/java/com/kezong/fataar/StyleAttr.java
Original file line number Diff line number Diff line change
@@ -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();
}

}
120 changes: 120 additions & 0 deletions source/src/main/java/com/kezong/fataar/ValuesHelper.java
Original file line number Diff line number Diff line change
@@ -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<Element> rootAttr = rootEle.elements(ELE_ATTR);
List<Element> styleableElements = rootEle.elements(ELE_DECLARE_STYLEABLE);

final Set<StyleAttr> repeatStyleAttr = new HashSet<>();
final Set<StyleAttr> styleAttrs = new HashSet<>();

//先查找根节点<attr
for (Element attr : rootAttr) {
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);
}
}
}

// 只保留第一个attr的定义
for (Element declareStyle : styleableElements) {
List<Element> 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;
}
}