mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-01 14:44:27 +02:00
implement destroy Block
This commit is contained in:
parent
53d8e192fa
commit
f81616f2f1
@ -201,7 +201,7 @@ public class ApkModule implements ApkFile {
|
|||||||
}
|
}
|
||||||
logVerbose("Dir validated: '"+path+"' -> '"+pathNew+"'");
|
logVerbose("Dir validated: '"+path+"' -> '"+pathNew+"'");
|
||||||
}
|
}
|
||||||
TableStringPool stringPool= getTableBlock().getTableStringPool();
|
TableStringPool stringPool= getTableBlock().getStringPool();
|
||||||
stringPool.refreshUniqueIdMap();
|
stringPool.refreshUniqueIdMap();
|
||||||
getTableBlock().refresh();
|
getTableBlock().refresh();
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ public class ApkModule implements ApkFile {
|
|||||||
}
|
}
|
||||||
logVerbose("Root changed: '"+path+"' -> '"+pathNew+"'");
|
logVerbose("Root changed: '"+path+"' -> '"+pathNew+"'");
|
||||||
}
|
}
|
||||||
TableStringPool stringPool= getTableBlock().getTableStringPool();
|
TableStringPool stringPool= getTableBlock().getStringPool();
|
||||||
stringPool.refreshUniqueIdMap();
|
stringPool.refreshUniqueIdMap();
|
||||||
getTableBlock().refresh();
|
getTableBlock().refresh();
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ public class ApkModule implements ApkFile {
|
|||||||
public List<ResFile> listResFiles(int resourceId, ResConfig resConfig) throws IOException {
|
public List<ResFile> listResFiles(int resourceId, ResConfig resConfig) throws IOException {
|
||||||
List<ResFile> results=new ArrayList<>();
|
List<ResFile> results=new ArrayList<>();
|
||||||
TableBlock tableBlock=getTableBlock();
|
TableBlock tableBlock=getTableBlock();
|
||||||
TableStringPool stringPool= tableBlock.getTableStringPool();
|
TableStringPool stringPool= tableBlock.getStringPool();
|
||||||
for(InputSource inputSource:getApkArchive().listInputSources()){
|
for(InputSource inputSource:getApkArchive().listInputSources()){
|
||||||
String name=inputSource.getAlias();
|
String name=inputSource.getAlias();
|
||||||
StringGroup<TableString> groupTableString = stringPool.get(name);
|
StringGroup<TableString> groupTableString = stringPool.get(name);
|
||||||
@ -274,7 +274,7 @@ public class ApkModule implements ApkFile {
|
|||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
public String getPackageName() throws IOException {
|
public String getPackageName(){
|
||||||
if(hasAndroidManifestBlock()){
|
if(hasAndroidManifestBlock()){
|
||||||
return getAndroidManifestBlock().getPackageName();
|
return getAndroidManifestBlock().getPackageName();
|
||||||
}
|
}
|
||||||
@ -289,7 +289,7 @@ public class ApkModule implements ApkFile {
|
|||||||
}
|
}
|
||||||
return pkg.getName();
|
return pkg.getName();
|
||||||
}
|
}
|
||||||
public void setPackageName(String name) throws IOException {
|
public void setPackageName(String name) {
|
||||||
String old=getPackageName();
|
String old=getPackageName();
|
||||||
if(hasAndroidManifestBlock()){
|
if(hasAndroidManifestBlock()){
|
||||||
getAndroidManifestBlock().setPackageName(name);
|
getAndroidManifestBlock().setPackageName(name);
|
||||||
@ -319,6 +319,46 @@ public class ApkModule implements ApkFile {
|
|||||||
return mTableBlock!=null
|
return mTableBlock!=null
|
||||||
|| getApkArchive().getInputSource(TableBlock.FILE_NAME)!=null;
|
|| getApkArchive().getInputSource(TableBlock.FILE_NAME)!=null;
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getApkArchive().clear();
|
||||||
|
AndroidManifestBlock manifestBlock = this.mManifestBlock;
|
||||||
|
if(manifestBlock!=null){
|
||||||
|
manifestBlock.destroy();
|
||||||
|
this.mManifestBlock = null;
|
||||||
|
}
|
||||||
|
TableBlock tableBlock = this.mTableBlock;
|
||||||
|
if(tableBlock!=null){
|
||||||
|
tableBlock.destroy();
|
||||||
|
this.mTableBlock = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void setManifest(AndroidManifestBlock manifestBlock){
|
||||||
|
APKArchive archive = getApkArchive();
|
||||||
|
if(manifestBlock==null){
|
||||||
|
mManifestBlock = null;
|
||||||
|
archive.remove(AndroidManifestBlock.FILE_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
manifestBlock.setApkFile(this);
|
||||||
|
BlockInputSource<AndroidManifestBlock> source =
|
||||||
|
new BlockInputSource<>(AndroidManifestBlock.FILE_NAME, manifestBlock);
|
||||||
|
archive.add(source);
|
||||||
|
mManifestBlock = manifestBlock;
|
||||||
|
}
|
||||||
|
public void setTableBlock(TableBlock tableBlock){
|
||||||
|
APKArchive archive = getApkArchive();
|
||||||
|
if(tableBlock==null){
|
||||||
|
mTableBlock = null;
|
||||||
|
archive.remove(TableBlock.FILE_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tableBlock.setApkFile(this);
|
||||||
|
BlockInputSource<TableBlock> source =
|
||||||
|
new BlockInputSource<>(TableBlock.FILE_NAME, tableBlock);
|
||||||
|
archive.add(source);
|
||||||
|
mTableBlock = tableBlock;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public AndroidManifestBlock getAndroidManifestBlock() {
|
public AndroidManifestBlock getAndroidManifestBlock() {
|
||||||
if(mManifestBlock!=null){
|
if(mManifestBlock!=null){
|
||||||
return mManifestBlock;
|
return mManifestBlock;
|
||||||
@ -374,7 +414,7 @@ public class ApkModule implements ApkFile {
|
|||||||
// loading packages and other chunk blocks for faster and less memory usage
|
// loading packages and other chunk blocks for faster and less memory usage
|
||||||
public TableStringPool getVolatileTableStringPool() throws IOException{
|
public TableStringPool getVolatileTableStringPool() throws IOException{
|
||||||
if(mTableBlock!=null){
|
if(mTableBlock!=null){
|
||||||
return mTableBlock.getTableStringPool();
|
return mTableBlock.getStringPool();
|
||||||
}
|
}
|
||||||
InputSource inputSource = getApkArchive()
|
InputSource inputSource = getApkArchive()
|
||||||
.getInputSource(TableBlock.FILE_NAME);
|
.getInputSource(TableBlock.FILE_NAME);
|
||||||
@ -388,7 +428,7 @@ public class ApkModule implements ApkFile {
|
|||||||
inputStream.close();
|
inputStream.close();
|
||||||
return stringPool;
|
return stringPool;
|
||||||
}
|
}
|
||||||
return getTableBlock().getTableStringPool();
|
return getTableBlock().getStringPool();
|
||||||
}
|
}
|
||||||
TableBlock loadTableBlock() throws IOException {
|
TableBlock loadTableBlock() throws IOException {
|
||||||
APKArchive archive=getApkArchive();
|
APKArchive archive=getApkArchive();
|
||||||
|
@ -13,47 +13,144 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.reandroid.apk;
|
package com.reandroid.apk;
|
||||||
|
|
||||||
import com.reandroid.archive.APKArchive;
|
import com.reandroid.archive.APKArchive;
|
||||||
import com.reandroid.archive.InputSource;
|
import com.reandroid.archive.ByteInputSource;
|
||||||
import com.reandroid.arsc.chunk.TableBlock;
|
import com.reandroid.archive.InputSource;
|
||||||
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
import com.reandroid.archive.InputSourceUtil;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlElement;
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
import com.reandroid.arsc.util.FrameworkTable;
|
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
||||||
import com.reandroid.arsc.value.ValueType;
|
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
|
||||||
|
import com.reandroid.arsc.chunk.xml.ResXmlElement;
|
||||||
|
import com.reandroid.arsc.util.FrameworkTable;
|
||||||
|
import com.reandroid.arsc.value.ValueType;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Produces compressed framework apk by removing unnecessary files and entries,
|
* Produces compressed framework apk by removing irrelevant files and entries,
|
||||||
* basically it keeps only resources.arsc and AndroidManifest.xml
|
* basically it keeps only resources.arsc and AndroidManifest.xml
|
||||||
*/
|
*/
|
||||||
public class FrameworkApk extends ApkModule{
|
public class FrameworkApk extends ApkModule{
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
private int versionCode;
|
||||||
|
private String versionName;
|
||||||
|
private String packageName;
|
||||||
|
private boolean mOptimizing;
|
||||||
|
private boolean mDestroyed;
|
||||||
public FrameworkApk(String moduleName, APKArchive apkArchive) {
|
public FrameworkApk(String moduleName, APKArchive apkArchive) {
|
||||||
super(moduleName, apkArchive);
|
super(moduleName, apkArchive);
|
||||||
|
super.setLoadDefaultFramework(false);
|
||||||
}
|
}
|
||||||
public FrameworkApk(APKArchive apkArchive) {
|
public FrameworkApk(APKArchive apkArchive) {
|
||||||
this("framework", apkArchive);
|
this("framework", apkArchive);
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public APKArchive getApkArchive() {
|
public void destroy(){
|
||||||
APKArchive archive=super.getApkArchive();
|
synchronized (mLock){
|
||||||
clearFiles(archive);
|
this.versionCode = -1;
|
||||||
return archive;
|
this.versionName = "-1";
|
||||||
}
|
this.packageName = "destroyed";
|
||||||
private void clearFiles(APKArchive archive){
|
super.destroy();
|
||||||
if(archive.entriesCount()==2){
|
this.mDestroyed = true;
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
synchronized (mLock){
|
||||||
|
if(!mDestroyed){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(hasTableBlock()){
|
||||||
|
this.versionCode = 0;
|
||||||
|
this.versionName = null;
|
||||||
|
this.packageName = null;
|
||||||
|
mDestroyed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersionCode() {
|
||||||
|
if(this.versionCode == 0){
|
||||||
|
initValues();
|
||||||
|
}
|
||||||
|
return this.versionCode;
|
||||||
|
}
|
||||||
|
public String getVersionName() {
|
||||||
|
if(this.versionName == null){
|
||||||
|
initValues();
|
||||||
|
}
|
||||||
|
return this.versionName;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getPackageName() {
|
||||||
|
if(this.packageName == null){
|
||||||
|
initValues();
|
||||||
|
}
|
||||||
|
return this.packageName;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
super.setPackageName(packageName);
|
||||||
|
this.packageName = null;
|
||||||
|
}
|
||||||
|
private void initValues() {
|
||||||
|
if(hasAndroidManifestBlock()){
|
||||||
|
AndroidManifestBlock manifest = getAndroidManifestBlock();
|
||||||
|
Integer code = manifest.getVersionCode();
|
||||||
|
if(code!=null){
|
||||||
|
this.versionCode = code;
|
||||||
|
}
|
||||||
|
if(this.versionName == null){
|
||||||
|
this.versionName = manifest.getVersionName();
|
||||||
|
}
|
||||||
|
if(this.packageName == null){
|
||||||
|
this.packageName = manifest.getPackageName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasTableBlock()){
|
||||||
|
FrameworkTable table = getTableBlock();
|
||||||
|
if(this.versionCode == 0 && table.isOptimized()){
|
||||||
|
int version = table.getVersionCode();
|
||||||
|
if(version!=0){
|
||||||
|
versionCode = version;
|
||||||
|
if(this.versionName == null){
|
||||||
|
this.versionName = String.valueOf(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this.packageName == null){
|
||||||
|
PackageBlock packageBlock = table.pickOne();
|
||||||
|
if(packageBlock!=null){
|
||||||
|
this.packageName = packageBlock.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setManifest(AndroidManifestBlock manifestBlock){
|
||||||
|
synchronized (mLock){
|
||||||
|
super.setManifest(manifestBlock);
|
||||||
|
this.versionCode = 0;
|
||||||
|
this.versionName = null;
|
||||||
|
this.packageName = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setTableBlock(TableBlock tableBlock){
|
||||||
|
synchronized (mLock){
|
||||||
|
super.setTableBlock(tableBlock);
|
||||||
|
this.versionCode = 0;
|
||||||
|
this.versionName = null;
|
||||||
|
this.packageName = null;
|
||||||
}
|
}
|
||||||
InputSource tableSource= archive.getInputSource(TableBlock.FILE_NAME);
|
|
||||||
InputSource manifestSource= archive.getInputSource(AndroidManifestBlock.FILE_NAME);
|
|
||||||
archive.clear();
|
|
||||||
archive.add(tableSource);
|
|
||||||
archive.add(manifestSource);
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public FrameworkTable getTableBlock() {
|
public FrameworkTable getTableBlock() {
|
||||||
@ -69,28 +166,60 @@ public class FrameworkApk extends ApkModule{
|
|||||||
InputStream inputStream = inputSource.openStream();
|
InputStream inputStream = inputSource.openStream();
|
||||||
FrameworkTable frameworkTable=FrameworkTable.load(inputStream);
|
FrameworkTable frameworkTable=FrameworkTable.load(inputStream);
|
||||||
frameworkTable.setApkFile(this);
|
frameworkTable.setApkFile(this);
|
||||||
if(hasAndroidManifestBlock()){
|
|
||||||
optimizeTable(frameworkTable);
|
|
||||||
}
|
|
||||||
BlockInputSource<FrameworkTable> blockInputSource=new BlockInputSource<>(inputSource.getName(), frameworkTable);
|
BlockInputSource<FrameworkTable> blockInputSource=new BlockInputSource<>(inputSource.getName(), frameworkTable);
|
||||||
blockInputSource.setMethod(inputSource.getMethod());
|
blockInputSource.setMethod(inputSource.getMethod());
|
||||||
blockInputSource.setSort(inputSource.getSort());
|
blockInputSource.setSort(inputSource.getSort());
|
||||||
archive.add(blockInputSource);
|
archive.add(blockInputSource);
|
||||||
return frameworkTable;
|
return frameworkTable;
|
||||||
}
|
}
|
||||||
private void optimizeTable(FrameworkTable table) throws IOException {
|
public void optimize(){
|
||||||
if(table.isOptimized()){
|
synchronized (mLock){
|
||||||
return;
|
if(mOptimizing){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!hasTableBlock()){
|
||||||
|
mOptimizing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FrameworkTable frameworkTable = getTableBlock();
|
||||||
|
if(frameworkTable.isOptimized()){
|
||||||
|
mOptimizing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FrameworkOptimizer optimizer = new FrameworkOptimizer(this);
|
||||||
|
optimizer.optimize();
|
||||||
|
mOptimizing = false;
|
||||||
}
|
}
|
||||||
int prev=table.countBytes();
|
}
|
||||||
logMessage("Optimizing ...");
|
public String getName(){
|
||||||
AndroidManifestBlock manifestBlock = getAndroidManifestBlock();
|
if(isDestroyed()){
|
||||||
String version=String.valueOf(manifestBlock.getVersionCode());
|
return "destroyed";
|
||||||
String name=manifestBlock.getPackageName();
|
}
|
||||||
table.optimize(name, version);
|
String pkg = getPackageName();
|
||||||
long diff=prev - table.countBytes();
|
if(pkg==null){
|
||||||
long percent=(diff*100L)/prev;
|
return "";
|
||||||
logMessage("Optimized: "+percent+" %");
|
}
|
||||||
|
return pkg + "-" + getVersionCode();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode(){
|
||||||
|
return Objects.hash(getClass(), getName());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj){
|
||||||
|
if(obj==this){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(getClass()!=obj.getClass()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FrameworkApk other = (FrameworkApk) obj;
|
||||||
|
return getName().equals(other.getName());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return getName();
|
||||||
}
|
}
|
||||||
public static FrameworkApk loadApkFile(File apkFile) throws IOException {
|
public static FrameworkApk loadApkFile(File apkFile) throws IOException {
|
||||||
APKArchive archive=APKArchive.loadZippedApk(apkFile);
|
APKArchive archive=APKArchive.loadZippedApk(apkFile);
|
||||||
@ -100,7 +229,7 @@ public class FrameworkApk extends ApkModule{
|
|||||||
APKArchive archive=APKArchive.loadZippedApk(apkFile);
|
APKArchive archive=APKArchive.loadZippedApk(apkFile);
|
||||||
return new FrameworkApk(moduleName, archive);
|
return new FrameworkApk(moduleName, archive);
|
||||||
}
|
}
|
||||||
public static boolean isFramework(ApkModule apkModule) throws IOException {
|
public static boolean isFramework(ApkModule apkModule) {
|
||||||
if(!apkModule.hasAndroidManifestBlock()){
|
if(!apkModule.hasAndroidManifestBlock()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -115,4 +244,27 @@ public class FrameworkApk extends ApkModule{
|
|||||||
}
|
}
|
||||||
return attribute.getValueAsBoolean();
|
return attribute.getValueAsBoolean();
|
||||||
}
|
}
|
||||||
}
|
public static FrameworkApk loadApkBuffer(InputStream inputStream) throws IOException{
|
||||||
|
return loadApkBuffer("framework", inputStream);
|
||||||
|
}
|
||||||
|
public static FrameworkApk loadApkBuffer(String moduleName, InputStream inputStream) throws IOException {
|
||||||
|
APKArchive archive = new APKArchive();
|
||||||
|
FrameworkApk frameworkApk = new FrameworkApk(moduleName, archive);
|
||||||
|
Map<String, ByteInputSource> inputSourceMap = InputSourceUtil.mapInputStreamAsBuffer(inputStream);
|
||||||
|
ByteInputSource source = inputSourceMap.get(TableBlock.FILE_NAME);
|
||||||
|
FrameworkTable tableBlock = new FrameworkTable();
|
||||||
|
if(source!=null){
|
||||||
|
tableBlock.readBytes(source.openStream());
|
||||||
|
}
|
||||||
|
frameworkApk.setTableBlock(tableBlock);
|
||||||
|
|
||||||
|
AndroidManifestBlock manifestBlock = new AndroidManifestBlock();
|
||||||
|
source = inputSourceMap.get(AndroidManifestBlock.FILE_NAME);
|
||||||
|
if(source!=null){
|
||||||
|
manifestBlock.readBytes(source.openStream());
|
||||||
|
}
|
||||||
|
frameworkApk.setManifest(manifestBlock);
|
||||||
|
archive.addAll(inputSourceMap.values());
|
||||||
|
return frameworkApk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -36,6 +36,14 @@ public class PackageArray extends BlockArray<PackageBlock>
|
|||||||
this.mPackageCount=packageCount;
|
this.mPackageCount=packageCount;
|
||||||
mPackageCount.setBlockLoad(this);
|
mPackageCount.setBlockLoad(this);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
Iterator<PackageBlock> itr = iterator(true);
|
||||||
|
while (itr.hasNext()){
|
||||||
|
PackageBlock packageBlock=itr.next();
|
||||||
|
packageBlock.destroy();
|
||||||
|
}
|
||||||
|
clearChildes();
|
||||||
|
}
|
||||||
public PackageBlock pickOne(){
|
public PackageBlock pickOne(){
|
||||||
PackageBlock[] items=getChildes();
|
PackageBlock[] items=getChildes();
|
||||||
if(items==null||items.length==0){
|
if(items==null||items.length==0){
|
||||||
|
@ -51,9 +51,12 @@ public abstract class StringArray<T extends StringItem> extends OffsetBlockArray
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
public List<T> removeUnusedStrings(){
|
public List<T> removeUnusedStrings(){
|
||||||
List<T> allUnused=listUnusedStrings();
|
List<T> unusedList=listUnusedStrings();
|
||||||
remove(allUnused);
|
remove(unusedList);
|
||||||
return allUnused;
|
for(T item:unusedList){
|
||||||
|
item.onRemoved();
|
||||||
|
}
|
||||||
|
return unusedList;
|
||||||
}
|
}
|
||||||
public List<T> listUnusedStrings(){
|
public List<T> listUnusedStrings(){
|
||||||
List<T> results=new ArrayList<>();
|
List<T> results=new ArrayList<>();
|
||||||
|
@ -31,6 +31,13 @@ public class StyleArray extends OffsetBlockArray<StyleItem> implements JSONConve
|
|||||||
setEndBytes(END_BYTE);
|
setEndBytes(END_BYTE);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public void clearChildes(){
|
||||||
|
for(StyleItem styleItem:listItems()){
|
||||||
|
styleItem.onRemoved();
|
||||||
|
}
|
||||||
|
super.clearChildes();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
void refreshEnd4Block(BlockReader reader, ByteArray end4Block) throws IOException {
|
void refreshEnd4Block(BlockReader reader, ByteArray end4Block) throws IOException {
|
||||||
end4Block.clear();
|
end4Block.clear();
|
||||||
if(reader.available()<4){
|
if(reader.available()<4){
|
||||||
|
@ -66,6 +66,14 @@ package com.reandroid.arsc.chunk;
|
|||||||
addChild(mSpecStringPool);
|
addChild(mSpecStringPool);
|
||||||
addChild(mBody);
|
addChild(mBody);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getEntriesGroupMap().clear();
|
||||||
|
getPackageBody().destroy();
|
||||||
|
getTypeStringPool().destroy();
|
||||||
|
getSpecStringPool().destroy();
|
||||||
|
setId(0);
|
||||||
|
setName("");
|
||||||
|
}
|
||||||
public Entry getOrCreate(String qualifiers, String type, String name){
|
public Entry getOrCreate(String qualifiers, String type, String name){
|
||||||
ResConfig resConfig = new ResConfig();
|
ResConfig resConfig = new ResConfig();
|
||||||
resConfig.parseQualifiers(qualifiers);
|
resConfig.parseQualifiers(qualifiers);
|
||||||
@ -162,6 +170,9 @@ package com.reandroid.arsc.chunk;
|
|||||||
public SpecStringPool getSpecStringPool(){
|
public SpecStringPool getSpecStringPool(){
|
||||||
return mSpecStringPool;
|
return mSpecStringPool;
|
||||||
}
|
}
|
||||||
|
public PackageBody getPackageBody() {
|
||||||
|
return mBody;
|
||||||
|
}
|
||||||
public SpecTypePairArray getSpecTypePairArray(){
|
public SpecTypePairArray getSpecTypePairArray(){
|
||||||
return mBody.getSpecTypePairArray();
|
return mBody.getSpecTypePairArray();
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ import java.util.*;
|
|||||||
implements MainChunk, JSONConvert<JSONObject>, EntryStore {
|
implements MainChunk, JSONConvert<JSONObject>, EntryStore {
|
||||||
private final TableStringPool mTableStringPool;
|
private final TableStringPool mTableStringPool;
|
||||||
private final PackageArray mPackageArray;
|
private final PackageArray mPackageArray;
|
||||||
private final Set<TableBlock> mFrameWorks=new HashSet<>();
|
private final List<TableBlock> mFrameWorks=new ArrayList<>();
|
||||||
private ApkFile mApkFile;
|
private ApkFile mApkFile;
|
||||||
public TableBlock() {
|
public TableBlock() {
|
||||||
super(new TableHeader(), 2);
|
super(new TableHeader(), 2);
|
||||||
@ -48,6 +48,16 @@ import java.util.*;
|
|||||||
addChild(mTableStringPool);
|
addChild(mTableStringPool);
|
||||||
addChild(mPackageArray);
|
addChild(mPackageArray);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getPackageArray().destroy();
|
||||||
|
getStringPool().destroy();
|
||||||
|
clearFrameworks();
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
public int countPackages(){
|
||||||
|
return getPackageArray().childesCount();
|
||||||
|
}
|
||||||
|
|
||||||
public PackageBlock pickOne(){
|
public PackageBlock pickOne(){
|
||||||
return getPackageArray().pickOne();
|
return getPackageArray().pickOne();
|
||||||
}
|
}
|
||||||
@ -232,7 +242,7 @@ import java.util.*;
|
|||||||
jsonObject.put(BuildInfo.NAME_arsc_lib_version, BuildInfo.getVersion());
|
jsonObject.put(BuildInfo.NAME_arsc_lib_version, BuildInfo.getVersion());
|
||||||
|
|
||||||
jsonObject.put(NAME_packages, getPackageArray().toJson());
|
jsonObject.put(NAME_packages, getPackageArray().toJson());
|
||||||
JSONArray jsonArray = getTableStringPool().toJson();
|
JSONArray jsonArray = getStringPool().toJson();
|
||||||
if(jsonArray!=null){
|
if(jsonArray!=null){
|
||||||
jsonObject.put(NAME_styled_strings, jsonArray);
|
jsonObject.put(NAME_styled_strings, jsonArray);
|
||||||
}
|
}
|
||||||
@ -247,8 +257,8 @@ import java.util.*;
|
|||||||
if(tableBlock==null||tableBlock==this){
|
if(tableBlock==null||tableBlock==this){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(getPackageArray().childesCount()==0 && getTableStringPool().countStrings()==0){
|
if(countPackages()==0 && getStringPool().countStrings()==0){
|
||||||
getTableStringPool().merge(tableBlock.getTableStringPool());
|
getStringPool().merge(tableBlock.getStringPool());
|
||||||
}
|
}
|
||||||
getPackageArray().merge(tableBlock.getPackageArray());
|
getPackageArray().merge(tableBlock.getPackageArray());
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -55,6 +55,16 @@
|
|||||||
addChild(mResXmlIDMap);
|
addChild(mResXmlIDMap);
|
||||||
addChild(mResXmlElementContainer);
|
addChild(mResXmlElementContainer);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
ResXmlElement root = getResXmlElement();
|
||||||
|
if(root!=null){
|
||||||
|
root.clearChildes();
|
||||||
|
setResXmlElement(null);
|
||||||
|
}
|
||||||
|
getResXmlIDMap().destroy();
|
||||||
|
getStringPool().destroy();
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
public void setAttributesUnitSize(int size, boolean setToAll){
|
public void setAttributesUnitSize(int size, boolean setToAll){
|
||||||
ResXmlElement root = getResXmlElement();
|
ResXmlElement root = getResXmlElement();
|
||||||
if(root!=null){
|
if(root!=null){
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
this.mResXmlIDArray=new ResXmlIDArray(getHeaderBlock());
|
this.mResXmlIDArray=new ResXmlIDArray(getHeaderBlock());
|
||||||
addChild(mResXmlIDArray);
|
addChild(mResXmlIDArray);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getResXmlIDArray().clearChildes();
|
||||||
|
}
|
||||||
public ResXmlIDArray getResXmlIDArray(){
|
public ResXmlIDArray getResXmlIDArray(){
|
||||||
return mResXmlIDArray;
|
return mResXmlIDArray;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,12 @@ public class BlockList<T extends Block> extends Block {
|
|||||||
super();
|
super();
|
||||||
mItems=new ArrayList<>();
|
mItems=new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
public void clearChildes(){
|
||||||
|
ArrayList<T> childList = new ArrayList<>(getChildes());
|
||||||
|
for(T child:childList){
|
||||||
|
remove(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
public void sort(Comparator<T> comparator){
|
public void sort(Comparator<T> comparator){
|
||||||
mItems.sort(comparator);
|
mItems.sort(comparator);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,14 @@ public class PackageBody extends FixedBlockContainer {
|
|||||||
addChild(4, mOverlayablePolicyList);
|
addChild(4, mOverlayablePolicyList);
|
||||||
addChild(5, mUnknownChunkList);
|
addChild(5, mUnknownChunkList);
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getSpecTypePairArray().clearChildes();
|
||||||
|
getLibraryBlock().getLibraryInfoArray().clearChildes();
|
||||||
|
getStagedAliasList().clearChildes();
|
||||||
|
getOverlayableList().clearChildes();
|
||||||
|
getOverlayablePolicyList().clearChildes();
|
||||||
|
getUnknownChunkList().clearChildes();
|
||||||
|
}
|
||||||
public OverlayableList getOverlayableList() {
|
public OverlayableList getOverlayableList() {
|
||||||
return mOverlayableList;
|
return mOverlayableList;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,13 @@ public class StringItem extends BlockItem implements JSONConvert<JSONObject> {
|
|||||||
ref.set(newIndex);
|
ref.set(newIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void onRemoved(){
|
||||||
|
StyleItem style = getStyle();
|
||||||
|
if(style!=null){
|
||||||
|
style.onRemoved();
|
||||||
|
}
|
||||||
|
setParent(null);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onIndexChanged(int oldIndex, int newIndex){
|
public void onIndexChanged(int oldIndex, int newIndex){
|
||||||
reUpdateReferences(newIndex);
|
reUpdateReferences(newIndex);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.item;
|
package com.reandroid.arsc.item;
|
||||||
|
|
||||||
import com.reandroid.arsc.base.Block;
|
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.arsc.model.StyleSpanInfo;
|
import com.reandroid.arsc.model.StyleSpanInfo;
|
||||||
import com.reandroid.arsc.pool.StringPool;
|
import com.reandroid.arsc.pool.StringPool;
|
||||||
@ -33,8 +32,10 @@ public class StyleItem extends IntegerArray implements JSONConvert<JSONObject> {
|
|||||||
super();
|
super();
|
||||||
this.mReferences = new HashSet<>();
|
this.mReferences = new HashSet<>();
|
||||||
}
|
}
|
||||||
void onRemoved(){
|
public void onRemoved(){
|
||||||
setStylePieceCount(0);
|
setStylePieceCount(0);
|
||||||
|
mSpanInfoList = null;
|
||||||
|
setParent(null);
|
||||||
}
|
}
|
||||||
public void onDataLoaded(){
|
public void onDataLoaded(){
|
||||||
linkAll();
|
linkAll();
|
||||||
|
@ -68,6 +68,10 @@ package com.reandroid.arsc.pool;
|
|||||||
|
|
||||||
mUniqueMap = new HashMap<>();
|
mUniqueMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
public void destroy(){
|
||||||
|
getStyleArray().clearChildes();
|
||||||
|
getStringsArray().clearChildes();
|
||||||
|
}
|
||||||
public List<String> toStringList(){
|
public List<String> toStringList(){
|
||||||
return getStringsArray().toStringList();
|
return getStringsArray().toStringList();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user