fix: generates code of missing R class (#353)
This commit is contained in:
@@ -91,7 +91,6 @@ public final class JadxDecompiler {
|
||||
|
||||
root.initClassPath();
|
||||
root.loadResources(getResources());
|
||||
root.initAppResClass();
|
||||
|
||||
initVisitors();
|
||||
}
|
||||
|
||||
@@ -94,10 +94,7 @@ public class RootNode {
|
||||
ResourceStorage resStorage = parser.getResStorage();
|
||||
constValues.setResourcesNames(resStorage.getResourcesNames());
|
||||
appPackage = resStorage.getAppPackage();
|
||||
}
|
||||
|
||||
public void initAppResClass() {
|
||||
appResClass = AndroidResourcesUtils.searchAppResClass(this);
|
||||
appResClass = AndroidResourcesUtils.searchAppResClass(this, resStorage);
|
||||
}
|
||||
|
||||
public void initClassPath() {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package jadx.core.utils.android;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -11,6 +16,8 @@ import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.DexNode;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.xmlgen.ResourceStorage;
|
||||
import jadx.core.xmlgen.entry.ResourceEntry;
|
||||
|
||||
/**
|
||||
* Android resources specific handlers
|
||||
@@ -21,7 +28,7 @@ public class AndroidResourcesUtils {
|
||||
private AndroidResourcesUtils() {
|
||||
}
|
||||
|
||||
public static ClassNode searchAppResClass(RootNode root) {
|
||||
public static ClassNode searchAppResClass(RootNode root, ResourceStorage resStorage) {
|
||||
String appPackage = root.getAppPackage();
|
||||
String fullName = appPackage != null ? appPackage + ".R" : "R";
|
||||
ClassNode resCls = root.searchClassByName(fullName);
|
||||
@@ -36,7 +43,7 @@ public class AndroidResourcesUtils {
|
||||
LOG.info("Found several 'R' class candidates: {}", candidates);
|
||||
}
|
||||
LOG.warn("Unknown 'R' class, create references to '{}'", fullName);
|
||||
return makeClass(root, fullName);
|
||||
return makeClass(root, fullName, resStorage);
|
||||
}
|
||||
|
||||
public static boolean handleAppResField(CodeWriter code, ClassGen clsGen, ClassInfo declClass) {
|
||||
@@ -50,12 +57,48 @@ public class AndroidResourcesUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ClassNode makeClass(RootNode root, String clsName) {
|
||||
private static ClassNode makeClass(RootNode root, String clsName, ResourceStorage resStorage) {
|
||||
List<DexNode> dexNodes = root.getDexNodes();
|
||||
if (dexNodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
ClassInfo r = ClassInfo.fromName(root, clsName);
|
||||
return new ClassNode(dexNodes.get(0), r);
|
||||
ClassNode classNode = new ClassNode(dexNodes.get(0), r);
|
||||
generateMissingRCode(classNode, resStorage);
|
||||
return classNode;
|
||||
}
|
||||
|
||||
private static void generateMissingRCode(ClassNode cls, ResourceStorage resStorage) {
|
||||
Map<String, List<ResourceEntry>> sortedMap = new HashMap<>();
|
||||
for(ResourceEntry ri : resStorage.getResources()) {
|
||||
List<ResourceEntry> entries = sortedMap.get(ri.getTypeName());
|
||||
if(entries == null) {
|
||||
entries = new LinkedList<>();
|
||||
sortedMap.put(ri.getTypeName(), entries);
|
||||
}
|
||||
entries.add(ri);
|
||||
}
|
||||
|
||||
Set<String> addedValues = new HashSet<>();
|
||||
CodeWriter clsCode = new CodeWriter();
|
||||
if (!"".equals(cls.getPackage())) {
|
||||
clsCode.add("package ").add(cls.getPackage()).add(';').newLine();
|
||||
}
|
||||
clsCode.startLine("public final class ").add(cls.getShortName()).add(" {").incIndent();
|
||||
for(String typeName : sortedMap.keySet()) {
|
||||
clsCode.startLine("public static final class ").add(typeName).add(" {").incIndent();
|
||||
for(ResourceEntry ri : sortedMap.get(typeName)) {
|
||||
if(addedValues.add(ri.getTypeName() + "." + ri.getKeyName())) {
|
||||
clsCode.startLine("public static final int ").add(ri.getKeyName()).add(" = ")
|
||||
.add("" + ri.getId()).add(";");
|
||||
}
|
||||
}
|
||||
clsCode.decIndent();
|
||||
clsCode.add("}");
|
||||
}
|
||||
clsCode.decIndent();
|
||||
clsCode.add("}");
|
||||
|
||||
cls.setCode(clsCode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user