Null Resources or Assets
Many Android developers have encountered crashes like this:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.AssetManager android.content.res.Resources.getAssets()' on a null object reference
at android.app.LoadedApk.getAssets(LoadedApk.java:581)
at android.app.LoadedApk.prepareResources(LoadedApk.java:643)
at android.app.LoadedApk.makeApplication(LoadedApk.java:636)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4673)
at android.app.ActivityThread.access$1500(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1409)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
The Root Cause
This issue typically occurs after an overlay installation when the App is launched by a Broadcast. Due to a system bug, the old APK is loaded. Common manifestations of this issue include:
- Context.getResources() returns
null - Class.getResourceAsStream() returns
null - Context.getAssets() throws
NullPointerException - Context.getSystemService(Context.AUDIO_SERVICE) throws
NullPointerException
How To Solve It?
For system bugs like this, which may be related to specific system versions, there's no universal solution. Therefore, Booster's approach is to check Resources and Assets when the Application starts. If Resources or AssetManager is null, the process is killed directly:
public class ResChecker {
public static void checkRes(final Application app) {
if (null == app.getAssets() || null == app.getResources()) {
final int pid = Process.myPid();
Log.w(TAG, "Process " + pid + " is going to be killed");
Process.killProcess(pid);
System.exit(10);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Getting Started
To fix the NullPointerException caused by overlay installation, simply include booster-transform-res-checkopen in new window, as shown below:
buildscript {
ext {
kotlin_version = "1.5.31"
booster_version = "4.16.3"
}
repositories {
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version"
/* Include this module */
classpath "com.didiglobal.booster:booster-transform-res-check:$booster_version"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
