Skip to content

Commit

Permalink
fix: generates code of missing R class (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
bagipro authored and skylot committed Sep 8, 2018
1 parent 8c43e7f commit 5de4d07
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
1 change: 0 additions & 1 deletion jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ public void load() {

root.initClassPath();
root.loadResources(getResources());
root.initAppResClass();

initVisitors();
}
Expand Down
5 changes: 1 addition & 4 deletions jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ public void loadResources(List<ResourceFile> resources) {
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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,6 +16,8 @@
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
Expand All @@ -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);
Expand All @@ -36,7 +43,7 @@ public static ClassNode searchAppResClass(RootNode root) {
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) {
Expand All @@ -50,12 +57,48 @@ public static boolean handleAppResField(CodeWriter code, ClassGen clsGen, ClassI
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);
}
}

0 comments on commit 5de4d07

Please sign in to comment.