Error encountered while compiling APK
I tried to modify the APK, but most of them gave an error: Attempt to invoke virtual method 'boolean com.reandroid.arsc.chunk.xml.ResXmIStartNamespace.removelfNoReference()' on a nullobject reference
`package com.nekolaska.apk
import android.app.Activity import com.luajava.LuaFunction import com.reandroid.apkeditor.Util import com.reandroid.apkeditor.compile.Builder import com.reandroid.apkeditor.decompile.Decompiler import java.io.File import kotlin.concurrent.thread
class Editor(private val context: Activity) { val cacheDir: String = File(context.cacheDir, "editor").absolutePath
fun start(
inApkPath: String,
outApkPath: String,
newPackage: String,
callback: LuaFunction<*>,
onError: LuaFunction<*>
) {
if (!File(inApkPath).exists()) {
onError.call("APK file does not exist")
return
}
thread {
decompile(inApkPath, newPackage, callback, onError)
build(outApkPath, callback, onError)
Util.deleteDir(File(cacheDir))
context.runOnUiThread {
callback.call("Task completed")
}
}
}
// Command line equivalent:
// java -jar C:\\Users\\NekoLaska\\Downloads\\APKEditor-1.3.9.jar d -i C:\\Users\\NekoLaska\\Downloads\\example.apk -o test_json
fun decompile(
apkPath: String,
newPackage: String,
callback: LuaFunction<*>,
onError: LuaFunction<*>
) = try {
decode(apkPath, newPackage, callback)
} catch (e: Exception) {
context.runOnUiThread {
callback.call("An exception occurred: " + e.message)
}
try {
decode(apkPath, newPackage, callback)
} catch (e: Exception) {
context.runOnUiThread {
onError.call("An exception occurred: " + e.message)
}
}
}
private fun decode(
apkPath: String,
newPackage: String,
callback: LuaFunction<*>,
) {
val outFile = File(cacheDir)
Util.deleteDir(outFile)
outFile.mkdirs()
Decompiler.execute(callback, "-i", apkPath, "-o", cacheDir)
modifyJson(newPackage)
modifyManifest(newPackage)
}
// Command line equivalent:
// java -jar C:\\Users\\NekoLaska\\Downloads\\APKEditor-1.3.9.jar b -i test_json -o test_edit.apk
fun build(apkPath: String, callback: LuaFunction<*>, onError: LuaFunction<*>) =
try {
File(apkPath).delete()
Builder.execute(callback, "-i", cacheDir, "-o", apkPath)
} catch (e: Exception) {
context.runOnUiThread {
callback.call("An exception occurred: " + e.message)
}
try {
File(apkPath).delete()
Builder.execute(callback, "-i", cacheDir, "-o", apkPath)
} catch (e: Exception) {
context.runOnUiThread {
onError.call("An exception occurred: " + e.message)
}
}
}
fun modifyJson(newPackage: String) {
val jsonPath = findJson()
var json = readString(jsonPath)
json = replacePackageText2(json!!, newPackage)
writeString(json, jsonPath)
}
fun modifyManifest(newPackage: String) {
val manifestPath = findManifest()
var manifest = readString(manifestPath)
manifest = replacePackageText(manifest!!, newPackage)
writeString(manifest, manifestPath)
}
fun writeString(str: String, path: String?) {
try {
if (path == null) {
return
}
val file = File(path)
file.writeText(str)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun readString(path: String?): String? {
try {
if (path == null) {
return null
}
val file = File(path)
return file.readText()
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
private fun replacePackageText(inputText: String, replacementText: String): String {
val pattern = "package=\\"([^\\"]*)\\""
return inputText.replace(pattern.toRegex(), "package=\\"$replacementText\\"")
}
private fun replacePackageText2(inputText: String, replacementText: String): String {
val pattern = "\\"package_name\\": \\"([^\\"]*)\\""
return inputText.replace(pattern.toRegex(), "\\"package_name\\": \\"$replacementText\\"")
}
private fun findFile(dirPath: String, fileName: String): String? {
val dir = File(dirPath) // Create a File object representing the specified directory path
if (!dir.exists()) { // If the directory doesn't exist, return null
return null
}
val files = dir.listFiles() ?: return null // Get list of all files in the directory, return null if empty
for (file in files) { // Iterate through the file list
if (file.isDirectory) {
val result = findFile(file.absolutePath, fileName)
if (result != null) { // If the file is found, return its path
return result
}
} else { // If it's a file
if (file.name.equals(fileName)) { // If the file name matches fileName, return its absolute path
return file.absolutePath
}
}
}
return null // If the file is not found, return null
}
fun findJson(): String? = findFile(cacheDir, "package.json")
fun findManifest(): String? = findFile(cacheDir, "AndroidManifest.xml")
}`
Attempt to invoke virtual method 'boolean com.reandroid.arsc.chunk.xml.ResXmlStartNamespace.removeIfNoReference()' on a null object reference java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.reandroid.arsc.chunk.xml.ResXmlStartNamespace.removeIfNoReference()' on a null object reference at com.reandroid.arsc.chunk.xml.ResXmlElement.removeUnusedNamespaces(ResXmlElement.java:306) at com.reandroid.arsc.chunk.xml.ResXmlDocument.removeUnusedNamespaces(ResXmlDocument.java:150) at com.reandroid.arsc.chunk.xml.ResXmlDocument.refreshFull(ResXmlDocument.java:170) at com.reandroid.arsc.chunk.xml.ResXmlDocument.parse(ResXmlDocument.java:481) at com.reandroid.apk.xmlencoder.XMLEncodeSource.encode(XMLEncodeSource.java:77) at com.reandroid.apk.xmlencoder.XMLEncodeSource.getArray(XMLEncodeSource.java:65) at com.reandroid.apk.xmlencoder.XMLEncodeSource.write(XMLEncodeSource.java:41) at com.reandroid.archive.writer.OutputSource.writeBuffer(OutputSource.java:58) at com.reandroid.archive.writer.FileOutputSource.writeBuffer(FileOutputSource.java:46) at com.reandroid.archive.writer.FileOutputSource.makeBuffer(FileOutputSource.java:42) at com.reandroid.archive.writer.ApkFileWriter.writeBuffer(ApkFileWriter.java:81) at com.reandroid.archive.writer.ApkFileWriter.prepareOutputs(ApkFileWriter.java:43) at com.reandroid.archive.writer.ApkFileWriter.prepareOutputs(ApkFileWriter.java:27) at com.reandroid.archive.writer.ApkWriter.write(ApkWriter.java:51) at com.reandroid.apk.ApkModule.writeApk(ApkModule.java:481) at com.reandroid.apkeditor.compile.Builder.buildXml(Builder.java:127) at com.reandroid.apkeditor.compile.Builder.run(Builder.java:52) at com.reandroid.apkeditor.compile.Builder.execute(Builder.java:191) at com.nekolaska.apk.Editor.build-0E7RQCE(Editor.kt:79) at com.nekolaska.apk.Editor.modify$lambda$2(Editor.kt:29) at com.nekolaska.apk.Editor.$r8$lambda$JaMRkojg8dzJ9SyjMfogwP69MsM(Unknown Source:0) at com.nekolaska.apk.Editor$$ExternalSyntheticLambda0.invoke(Unknown Source:12) at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
Null at removeUnusedNamespaces could not happen, the base collection is BlockList so this doesn't store null items at all.
- Kotlin stripped stack trace (most likely), change to java to confirm
- Maybe you are running in multiple threads (ARSCLib is not thread safe)
FYI: If your end goal is to edit resources/xml, you don't have to decompile at all. There are all the methods to edit binary files directly.
Null at
removeUnusedNamespacescould not happen, the base collection isBlockListso this doesn't store null items at all.
- Kotlin stripped stack trace (most likely), change to java to confirm
- Maybe you are running in multiple threads (ARSCLib is not thread safe)
FYI: If your end goal is to edit resources/xml, you don't have to decompile at all. There are all the methods to edit binary files directly.
Hi, I need to modify the resource/xml code, how can I edit the binary file directly? Is there any example usage?
Null at
removeUnusedNamespacescould not happen, the base collection isBlockListso this doesn't store null items at all.
- Kotlin stripped stack trace (most likely), change to java to confirm
- Maybe you are running in multiple threads (ARSCLib is not thread safe)
FYI: If your end goal is to edit resources/xml, you don't have to decompile at all. There are all the methods to edit binary files directly.
Sorry, I need to change the package name, but I don't know how to directly edit binary file resources and xml. Please provide the following sample code
@cgapk123 Confirm :https://github.com/REAndroid/ARSCLib/commit/c8002afd48cc613b3f74a8d3f5a92b4d6c945259 fixes this issue