diff --git a/build.gradle b/build.gradle index db1c9d5..83d0cfa 100755 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'java-library' group 'com.reandroid.lib.arsc' -version '1.0.1' +version '1.0.2' java { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java b/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java index 7da21f6..2d56f09 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java @@ -4,8 +4,6 @@ import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.value.EntryBlock; -import java.util.Iterator; - public class EntryBlockArray extends OffsetBlockArray { public EntryBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){ @@ -22,7 +20,9 @@ public class EntryBlockArray extends OffsetBlockArray { if(entryBlock!=null){ return entryBlock; } - ensureSize(entryId+1); + int count=entryId+1; + ensureSize(count); + refreshCount(); return get(entryId); } public EntryBlock getEntry(short entryId){ diff --git a/src/main/java/com/reandroid/lib/arsc/array/OffsetBlockArray.java b/src/main/java/com/reandroid/lib/arsc/array/OffsetBlockArray.java index 1492f9f..2ae3725 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/OffsetBlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/OffsetBlockArray.java @@ -105,7 +105,7 @@ public abstract class OffsetBlockArray extends BlockArray im refreshCount(); refreshStart(); } - private void refreshCount(){ + void refreshCount(){ mItemCount.set(childesCount()); } private void refreshStart(){ diff --git a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java index 24d10ad..77c5bca 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java @@ -5,9 +5,7 @@ import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.container.SpecTypePair; import com.reandroid.lib.arsc.value.EntryBlock; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; public class SpecTypePairArray extends BlockArray { public SpecTypePairArray(){ @@ -114,4 +112,32 @@ public class SpecTypePairArray extends BlockArray { protected void onRefreshed() { } + @Override + protected void onPreRefreshRefresh(){ + validateEntryCounts(); + } + // For android API < 26, it is required to have equal entry count on all SpecTypePair + private void validateEntryCounts(){ + Map entryCountMap=mapHighestEntryCount(); + for(Map.Entry entry:entryCountMap.entrySet()){ + byte id=entry.getKey(); + int count=entry.getValue(); + SpecTypePair pair=getPair(id); + pair.getSpecBlock().setEntryCount(count); + pair.getTypeBlockArray().setEntryCount(count); + } + } + private Map mapHighestEntryCount(){ + Map results=new HashMap<>(); + SpecTypePair[] childes=getChildes(); + for (SpecTypePair pair:childes){ + int count=pair.getHighestEntryCount(); + byte id=pair.getTypeId(); + Integer exist=results.get(id); + if(exist==null || count>exist){ + results.put(id, count); + } + } + return results; + } } diff --git a/src/main/java/com/reandroid/lib/arsc/array/StringArray.java b/src/main/java/com/reandroid/lib/arsc/array/StringArray.java index 877d169..4c5dffe 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/StringArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/StringArray.java @@ -9,6 +9,7 @@ import java.util.List; public abstract class StringArray extends OffsetBlockArray{ private boolean mUtf8; + public StringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { super(offsets, itemCount, itemStart); this.mUtf8=is_utf8; diff --git a/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java b/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java index 6518d16..ce0dc31 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java @@ -7,6 +7,7 @@ import com.reandroid.lib.arsc.chunk.SpecBlock; import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.io.BlockReader; +import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; @@ -207,4 +208,28 @@ public class TypeBlockArray extends BlockArray { typeBlock.readBytes(reader); return reader.getPosition()>pos; } + public int getHighestEntryCount(){ + int result=0; + for(TypeBlock typeBlock:getChildes()){ + int count=typeBlock.getEntryCount(); + if(count>result){ + result=count; + } + } + return result; + } + public void setEntryCount(int count){ + for(TypeBlock typeBlock:getChildes()){ + typeBlock.setEntryCount(count); + } + } + public TypeString getTypeString(){ + for(TypeBlock typeBlock:getChildes()){ + TypeString typeString=typeBlock.getTypeString(); + if(typeString!=null){ + return typeString; + } + } + return null; + } } diff --git a/src/main/java/com/reandroid/lib/arsc/array/TypeStringArray.java b/src/main/java/com/reandroid/lib/arsc/array/TypeStringArray.java index 8b58e11..8dba6b3 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/TypeStringArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/TypeStringArray.java @@ -5,12 +5,17 @@ import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.TypeString; public class TypeStringArray extends StringArray { + private int lastCreateIndex; public TypeStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { super(offsets, itemCount, itemStart, is_utf8); } @Override public TypeString newInstance() { - return new TypeString(isUtf8()); + TypeString typeString=new TypeString(isUtf8()); + //create default name + this.lastCreateIndex++; + typeString.set("type-"+lastCreateIndex); + return typeString; } @Override public TypeString[] newInstance(int len) { 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 1667c8f..f7dee78 100755 --- a/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/base/BlockArray.java @@ -157,7 +157,7 @@ public abstract class BlockArray extends BlockContainer impl int result=-1; for(int i=0;i extends Block{ parent=parent.getParent(); } return result; + } + protected void onPreRefreshRefresh(){ + } protected abstract void onRefreshed(); public final void refresh(){ if(isNull()){ return; } + onPreRefreshRefresh(); refreshChildes(); onRefreshed(); } @@ -36,7 +40,7 @@ public abstract class BlockContainer extends Block{ for(int i=0;i container=(BlockContainer)item; container.refresh(); } } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java index d39810f..5634b67 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java @@ -8,6 +8,7 @@ import com.reandroid.lib.arsc.group.EntryGroup; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.PackageName; import com.reandroid.lib.arsc.item.ReferenceItem; +import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.pool.SpecStringPool; import com.reandroid.lib.arsc.pool.TableStringPool; import com.reandroid.lib.arsc.pool.TypeStringPool; diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java index dc4f7d1..b0fba2b 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java @@ -50,13 +50,6 @@ public class TableBlock extends BaseChunk { refreshPackageCount(); } - @Override - public int onWriteBytes(OutputStream stream) throws IOException{ - int result=super.onWriteBytes(stream); - stream.flush(); - stream.close(); - return result; - } public void readBytes(File file) throws IOException{ BlockReader reader=new BlockReader(file); super.readBytes(reader); @@ -74,7 +67,9 @@ public class TableBlock extends BaseChunk { dir.mkdirs(); } OutputStream outputStream=new FileOutputStream(file); - return super.writeBytes(outputStream); + int length = super.writeBytes(outputStream); + outputStream.close(); + return length; } @Override diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlBlock.java index 1e0ff56..e130d03 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlBlock.java @@ -107,13 +107,6 @@ public class ResXmlBlock extends BaseChunk { @Override protected void onChunkRefreshed() { - } - @Override - public int onWriteBytes(OutputStream stream) throws IOException{ - int result=super.onWriteBytes(stream); - stream.flush(); - stream.close(); - return result; } public void readBytes(File file) throws IOException{ BlockReader reader=new BlockReader(file); @@ -132,7 +125,9 @@ public class ResXmlBlock extends BaseChunk { dir.mkdirs(); } OutputStream outputStream=new FileOutputStream(file); - return super.writeBytes(outputStream); + int length = super.writeBytes(outputStream); + outputStream.close(); + return length; } public static boolean isResXmlBlock(File file){ diff --git a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java index f85b51c..81d732f 100755 --- a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java +++ b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java @@ -9,6 +9,7 @@ import com.reandroid.lib.arsc.chunk.SpecBlock; import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.io.BlockReader; +import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; @@ -128,5 +129,15 @@ public class SpecTypePair extends BlockContainer { private void readUnexpectedNonSpecBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{ throw new IOException("Unexpected block: "+headerBlock.toString()+", Should be: "+ChunkType.SPEC); } - + public int getHighestEntryCount(){ + int specEntryCount=getSpecBlock().getEntryCount(); + int typeEntryCount=getTypeBlockArray().getHighestEntryCount(); + if(specEntryCount>typeEntryCount){ + return specEntryCount; + } + return typeEntryCount; + } + public TypeString getTypeString(){ + return getTypeBlockArray().getTypeString(); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java b/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java index 11dbbf7..8585271 100755 --- a/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java +++ b/src/main/java/com/reandroid/lib/arsc/io/BlockReader.java @@ -306,7 +306,9 @@ public class BlockReader extends InputStream { private static byte[] loadBuffer(File file) throws IOException { FileInputStream in=new FileInputStream(file); - return loadBuffer(in); + byte[] result = loadBuffer(in); + in.close(); + return result; } private static byte[] loadBuffer(InputStream in) throws IOException { byte[] result=new byte[0]; diff --git a/src/main/java/com/reandroid/lib/arsc/pool/TypeStringPool.java b/src/main/java/com/reandroid/lib/arsc/pool/TypeStringPool.java index db1cdf7..e6e84ca 100755 --- a/src/main/java/com/reandroid/lib/arsc/pool/TypeStringPool.java +++ b/src/main/java/com/reandroid/lib/arsc/pool/TypeStringPool.java @@ -2,6 +2,7 @@ package com.reandroid.lib.arsc.pool; import com.reandroid.lib.arsc.array.StringArray; import com.reandroid.lib.arsc.array.TypeStringArray; +import com.reandroid.lib.arsc.group.StringGroup; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.TypeString; @@ -13,6 +14,12 @@ public class TypeStringPool extends BaseStringPool { public TypeString getById(int id){ return super.get(id-1); } + public TypeString getOrCreate(int typeId, String typeName){ + getStringsArray().ensureSize(typeId); + TypeString typeString=getById(typeId); + typeString.set(typeName); + return typeString; + } @Override StringArray newInstance(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { return new TypeStringArray(offsets, itemCount, itemStart, is_utf8); diff --git a/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java b/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java index 8d7b236..a4094bd 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java +++ b/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java @@ -1,22 +1,14 @@ package com.reandroid.lib.arsc.value; import com.reandroid.lib.arsc.base.Block; -import com.reandroid.lib.arsc.chunk.PackageBlock; -import com.reandroid.lib.arsc.chunk.TableBlock; import com.reandroid.lib.arsc.item.BlockItem; -import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.ReferenceItem; -import com.reandroid.lib.arsc.pool.SpecStringPool; -import com.reandroid.lib.arsc.pool.TableStringPool; - -import java.util.List; public abstract class BaseResValue extends BlockItem { BaseResValue(int bytesLength){ super(bytesLength); } - public EntryBlock getEntryBlock(){ Block parent=getParent(); while(parent!=null){ @@ -27,7 +19,6 @@ public abstract class BaseResValue extends BlockItem { } return null; } - boolean removeSpecReference(ReferenceItem ref){ EntryBlock entryBlock=getEntryBlock(); if(entryBlock==null){ @@ -56,15 +47,10 @@ public abstract class BaseResValue extends BlockItem { } entryBlock.addTableReference(ref); } - - - @Override public void onBytesChanged() { } - - int getInt(int offset){ byte[] bts = getBytesInternal(); return bts[offset] & 0xff | @@ -83,7 +69,6 @@ public abstract class BaseResValue extends BlockItem { bts[offset]= (byte) (val & 0xff); onBytesChanged(); } - void setShort(int offset, short val){ if(val==getShort(offset)){ return; diff --git a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java index 5c52e15..3d066c9 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java @@ -17,7 +17,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -public class EntryBlock extends Block { +public class EntryBlock extends Block{ private ShortItem mHeaderSize; private ShortItem mFlags; private IntegerItem mSpecReference; @@ -189,9 +189,13 @@ public class EntryBlock extends Block { public void setFlagComplex(boolean is_complex){ if(is_complex){ - setFlags(FLAG_COMPLEX); + if(!isFlagsComplex()){ + setFlags(FLAG_COMPLEX); + } }else { - setFlags(FLAG_INT); + if(isFlagsComplex()){ + setFlags(FLAG_INT); + } } refreshHeaderSize(); } @@ -437,7 +441,14 @@ public class EntryBlock extends Block { if(isNull()){ return 0; } - return 8+mResValue.countBytes(); + /* + mHeaderSize -> 2 bytes + mFlags -> 2 bytes + mSpecReference -> 4 bytes + ------- + Total = 8 bytes, thus this value is always fixed no need to re-count + */ + return 8 + mResValue.countBytes(); } @Override public void onCountUpTo(BlockCounter counter) { @@ -514,6 +525,7 @@ public class EntryBlock extends Block { updatePackage(); updateSpecRef(); } + @Override public String toString(){ StringBuilder builder=new StringBuilder(); builder.append(getClass().getSimpleName()); @@ -566,9 +578,10 @@ public class EntryBlock extends Block { private final static short FLAG_COMPLEX_MASK = 0x0001; - private final static short FLAG_COMPLEX = 0x0003; - private final static short FLAG_INT = 0x0002; + private final static short FLAG_COMPLEX = 0x0001; + private final static short FLAG_INT = 0x0000; private final static short HEADER_COMPLEX=0x0010; private final static short HEADER_INT=0x0008; + } diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResValueInt.java b/src/main/java/com/reandroid/lib/arsc/value/ResValueInt.java index ca8dc9e..66b92a8 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResValueInt.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResValueInt.java @@ -2,8 +2,6 @@ package com.reandroid.lib.arsc.value; import com.reandroid.lib.arsc.decoder.ValueDecoder; import com.reandroid.lib.arsc.io.BlockReader; -import com.reandroid.lib.arsc.item.ReferenceItem; - import java.io.IOException;