diff --git a/src/main/java/com/reandroid/apk/ApkModule.java b/src/main/java/com/reandroid/apk/ApkModule.java index f829cf3..9ce1aee 100644 --- a/src/main/java/com/reandroid/apk/ApkModule.java +++ b/src/main/java/com/reandroid/apk/ApkModule.java @@ -27,6 +27,7 @@ import com.reandroid.arsc.container.SpecTypePair; import com.reandroid.arsc.group.StringGroup; import com.reandroid.arsc.item.TableString; import com.reandroid.arsc.pool.TableStringPool; +import com.reandroid.arsc.util.FrameworkTable; import com.reandroid.arsc.value.Entry; import com.reandroid.arsc.value.ResConfig; import com.reandroid.common.Frameworks; @@ -56,6 +57,57 @@ public class ApkModule implements ApkFile { this.mUncompressedFiles=new UncompressedFiles(); this.mUncompressedFiles.addPath(apkArchive); } + public void initializeAndroidFramework() throws IOException { + if(!hasTableBlock()){ + return; + } + initializeAndroidFramework(getTableBlock()); + } + private void initializeAndroidFramework(TableBlock tableBlock) throws IOException { + if(tableBlock == null || isAndroid(tableBlock)){ + return; + } + List frameWorkList = tableBlock.getFrameWorks(); + for(TableBlock frameWork:frameWorkList){ + if(isAndroid(frameWork)){ + return; + } + } + logMessage("Initializing android framework ..."); + Integer version = getAndroidFrameworkVersion(); + FrameworkApk frameworkApk; + if(version==null){ + logMessage("Can not read framework version from manifest, loading latest"); + frameworkApk = AndroidFrameworks.getLatest(); + }else { + logMessage("Loading android framework for version: " + version); + frameworkApk = AndroidFrameworks.getBestMatch(version); + } + FrameworkTable frameworkTable = frameworkApk.getTableBlock(); + tableBlock.addFramework(frameworkTable); + logMessage("Initialized framework: "+frameworkApk.getName()); + } + private boolean isAndroid(TableBlock tableBlock){ + if(tableBlock instanceof FrameworkTable){ + FrameworkTable frameworkTable = (FrameworkTable) tableBlock; + return frameworkTable.isAndroid(); + } + return false; + } + public Integer getAndroidFrameworkVersion(){ + if(!hasAndroidManifestBlock()){ + return null; + } + AndroidManifestBlock manifestBlock = getAndroidManifestBlock(); + Integer version = manifestBlock.getCompileSdkVersion(); + if(version == null){ + version = manifestBlock.getPlatformBuildVersionCode(); + } + if(version == null){ + version = manifestBlock.getTargetSdkVersion(); + } + return version; + } public void removeResFilesWithEntry(int resourceId) throws IOException { removeResFilesWithEntry(resourceId, null, true); } @@ -392,6 +444,9 @@ public class ApkModule implements ApkFile { } try { mTableBlock = loadTableBlock(); + if(loadDefaultFramework){ + initializeAndroidFramework(mTableBlock); + } } catch (IOException exception) { throw new IllegalArgumentException(exception); } @@ -442,15 +497,11 @@ public class ApkModule implements ApkFile { }else if(inputSource instanceof SingleJsonTableInputSource){ tableBlock=((SingleJsonTableInputSource)inputSource).getTableBlock(); }else if(inputSource instanceof BlockInputSource){ - Chunk block = ((BlockInputSource) inputSource).getBlock(); - tableBlock=(TableBlock) block; + Chunk block = ((BlockInputSource) inputSource).getBlock(); + tableBlock = (TableBlock) block; }else { InputStream inputStream = inputSource.openStream(); - if(loadDefaultFramework){ - tableBlock=TableBlock.loadWithAndroidFramework(inputStream); - }else { - tableBlock=TableBlock.load(inputStream); - } + tableBlock = TableBlock.load(inputStream); inputStream.close(); } BlockInputSource blockInputSource=new BlockInputSource<>(inputSource.getName(), tableBlock); diff --git a/src/main/java/com/reandroid/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/arsc/chunk/TableBlock.java index df0e2f9..d08dda3 100755 --- a/src/main/java/com/reandroid/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/arsc/chunk/TableBlock.java @@ -279,6 +279,7 @@ import java.util.*; return builder.toString(); } + @Deprecated public static TableBlock loadWithAndroidFramework(InputStream inputStream) throws IOException{ TableBlock tableBlock=load(inputStream); tableBlock.addFramework(Frameworks.getAndroid()); diff --git a/src/main/java/com/reandroid/arsc/util/FrameworkTable.java b/src/main/java/com/reandroid/arsc/util/FrameworkTable.java index e4b7118..e86ffca 100755 --- a/src/main/java/com/reandroid/arsc/util/FrameworkTable.java +++ b/src/main/java/com/reandroid/arsc/util/FrameworkTable.java @@ -37,6 +37,7 @@ public class FrameworkTable extends TableBlock { private String frameworkName; private int versionCode; + private int mainPackageId; private ResNameMap mNameGroupMap; private boolean mOptimized; private boolean mOptimizeChecked; @@ -44,14 +45,28 @@ public class FrameworkTable extends TableBlock { super(); } + public boolean isAndroid(){ + return "android".equals(getFrameworkName()) + && getMainPackageId() == 0x01; + } + + public int getMainPackageId() { + if(mainPackageId!=0){ + return mainPackageId; + } + PackageBlock packageBlock = pickOne(); + if(packageBlock!=null){ + mainPackageId = packageBlock.getId(); + } + return mainPackageId; + } + @Override public void destroy(){ - ResNameMap nameGroupMap = this.mNameGroupMap; - if(nameGroupMap!=null){ - nameGroupMap.clear(); - } + clearResourceNameMap(); this.frameworkName = null; this.versionCode = 0; + this.mainPackageId = 0; super.destroy(); } public int resolveResourceId(String typeName, String entryName){ @@ -141,6 +156,15 @@ public class FrameworkTable extends TableBlock { if(frameworkName == null){ frameworkName = loadProperty(PROP_NAME); } + if(frameworkName == null){ + PackageBlock packageBlock = pickOne(); + if(packageBlock!=null){ + String name = packageBlock.getName(); + if(name!=null && !name.trim().isEmpty()){ + frameworkName = name; + } + } + } return frameworkName; } public void setFrameworkName(String value){