diff --git a/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java b/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java index 9da8ed7..d1a74bb 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/ResXmlAttributeArray.java @@ -11,10 +11,7 @@ import com.reandroid.lib.json.JSONArray; import com.reandroid.lib.json.JSONObject; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.Comparator; -import java.util.List; public class ResXmlAttributeArray extends BlockArray implements Comparator, JSONConvert { @@ -27,14 +24,7 @@ public class ResXmlAttributeArray extends BlockArray this.mAttributeCount=attributeCount; } public void sortAttributes(){ - Collection items = listItems(); - if(items.size()<2){ - return; - } - List elementList = new ArrayList<>(items); - elementList.sort(this); - clearChildes(); - addAll(elementList.toArray(new ResXmlAttribute[0])); + sort(this); } private void refreshCount(){ short count= (short) childesCount(); @@ -76,6 +66,7 @@ public class ResXmlAttributeArray extends BlockArray @Override public JSONArray toJson() { + sortAttributes(); JSONArray jsonArray=new JSONArray(); int i=0; for(ResXmlAttribute attr:listItems()){ diff --git a/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java b/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java index ce09ef0..ed6c120 100755 --- a/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java @@ -66,7 +66,6 @@ public abstract class BlockArray extends BlockContainer impl } elementData=newInstance(0); } - public void addAll(T[] blocks){ if(blocks==null||blocks.length==0){ return; @@ -98,6 +97,16 @@ public abstract class BlockArray extends BlockContainer impl trimNullBlocks(); } } + public void sort(Comparator comparator){ + T[] data=this.elementData; + if(comparator==null || data==null || data.length<2){ + return; + } + Arrays.sort(data, 0, data.length, comparator); + for(int i=0;i extends BlockContainer impl item.setParent(this); } elementData=update; - Arrays.fill(old, null); } @Override @@ -293,7 +301,7 @@ public abstract class BlockArray extends BlockContainer impl private class BlockIterator implements Iterator { private int mCursor; - private int mMaxSize; + private final int mMaxSize; private final boolean mSkipNullBlock; BlockIterator(boolean skipNullBlock){ mSkipNullBlock=skipNullBlock; diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java index aa09615..56f3c34 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java @@ -302,7 +302,6 @@ public class ResXmlAttribute extends FixedBlockContainer setRawValue(val); setValueStringReference(-1); } - private String getCompareName(){ int id=getNameResourceID(); StringBuilder builder=new StringBuilder(); @@ -317,7 +316,26 @@ public class ResXmlAttribute extends FixedBlockContainer } @Override public int compareTo(ResXmlAttribute other) { - return getCompareName().compareTo(other.getCompareName()); + int id1=getNameResourceID(); + int id2=other.getNameResourceID(); + if(id1==0 && id2!=0){ + return 1; + } + if(id2==0 && id1!=0){ + return -1; + } + if(id1!=0){ + return Integer.compare(id1, id2); + } + String name1=getName(); + if(name1==null){ + name1=""; + } + String name2=other.getName(); + if(name2==null){ + name2=""; + } + return name1.compareTo(name2); } @Override diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java index f6e9100..148197c 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java @@ -2,11 +2,8 @@ package com.reandroid.lib.arsc.chunk.xml; import com.reandroid.lib.arsc.chunk.ChunkType; import com.reandroid.lib.arsc.array.ResXmlAttributeArray; -import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.ShortItem; -import com.reandroid.lib.arsc.pool.ResXmlStringPool; -import java.io.IOException; import java.util.Collection; @@ -37,18 +34,6 @@ public class ResXmlStartElement extends BaseXmlChunk { addChild(mAttributeArray); } @Override - public void onReadBytes(BlockReader reader) throws IOException { - super.onReadBytes(reader); - if(mClassAttributePosition.get()==0 && mStyleAttributePosition.get()==0){ - return; - } - ResXmlStringPool stringPool=getStringPool(); - int c=(mClassAttributePosition.get() & 0xffff)-1; - int style = (mStyleAttributePosition.get() >>> 16) - 1; - int z=c+style; - stringPool.childesCount(); - } - @Override protected void onPreRefreshRefresh(){ sortAttributes(); } @@ -66,24 +51,22 @@ public class ResXmlStartElement extends BaseXmlChunk { if(classAttribute!=null){ mClassAttributePosition.set((short) (classAttribute.getIndex()+1)); // In case obfuscation - if(!"class".equals(classAttribute.getName())){ - classAttribute.setName("class", 0); + if(!ATTRIBUTE_NAME_CLASS.equals(classAttribute.getName())){ + classAttribute.setName(ATTRIBUTE_NAME_CLASS, 0); } } if(styleAttribute!=null){ mStyleAttributePosition.set((short) (styleAttribute.getIndex()+1)); // In case obfuscation - if(!"style".equals(styleAttribute.getName())){ - styleAttribute.setName("style", 0); + if(!ATTRIBUTE_NAME_STYLE.equals(styleAttribute.getName())){ + styleAttribute.setName(ATTRIBUTE_NAME_STYLE, 0); } } } void calculatePositions(){ - - int android_id=0x010100d0; - ResXmlAttribute idAttribute=getAttribute(android_id); - ResXmlAttribute classAttribute=getNoIdAttribute("class"); - ResXmlAttribute styleAttribute=getNoIdAttribute("style"); + ResXmlAttribute idAttribute=getAttribute(ATTRIBUTE_RESOURCE_ID_id); + ResXmlAttribute classAttribute=getNoIdAttribute(ATTRIBUTE_NAME_CLASS); + ResXmlAttribute styleAttribute=getNoIdAttribute(ATTRIBUTE_NAME_STYLE); if(idAttribute!=null){ mIdAttributePosition.set((short) (idAttribute.getIndex()+1)); @@ -244,4 +227,17 @@ public class ResXmlStartElement extends BaseXmlChunk { private static final short ATTRIBUTES_UNIT_SIZE=0x0014; private static final short ATTRIBUTES_DEFAULT_START=0x0014; + /* + * Find another way to mark an attribute is class, device actually relies on + * value of mClassAttributePosition */ + private static final String ATTRIBUTE_NAME_CLASS="class"; + /* + * Find another way to mark an attribute is style, device actually relies on + * value of mStyleAttributePosition */ + private static final String ATTRIBUTE_NAME_STYLE="style"; + /* + * Resource id value of attribute 'android:id' + * instead of relying on hardcoded value, we should find another way to + * mark an attribute is 'id' */ + private static final int ATTRIBUTE_RESOURCE_ID_id =0x010100d0; }