Crash is observed at approximately in 3-5% users, in the rest updates works as expected.
Launch manager when Activity creates
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UpdatesManager.getInstance().checkUpdates(this);
}
@Override
protected void onResume() {
super.onResume();
UpdatesManager.getInstance().proposeToInstallDownloadedUpdate(this);
}
@Override
protected void onStop() {
UpdatesManager.getInstance().unregisterListener();
super.onStop();
}
@Override
protected void onDestroy() {
UpdatesManager.getInstance().removeInstance();
super.onDestroy();
}
}
Actually manager
public class UpdatesManager {
private static volatile UpdatesManager updatesManager = null;
private AppUpdateManager appUpdateManager;
private InstallStateUpdatedListener installStateUpdatedListener;
private ActivityResultLauncher<IntentSenderRequest> activityResultLauncher;
private UpdatesManager() {
}
public static synchronized UpdatesManager getInstance() {
if (updatesManager == null) {
updatesManager = new UpdatesManager();
}
return updatesManager;
}
public void checkUpdates(MainActivity mainActivity) {
registerResultLauncher(mainActivity);
appUpdateManager = AppUpdateManagerFactory.create(mainActivity);
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
if (activityResultLauncher != null) {
appUpdateInfoTask.addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
@Override
public void onSuccess(AppUpdateInfo appUpdateInfo) {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
//
//
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, activityResultLauncher, AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build());
}
}
});
installStateUpdatedListener = new InstallStateUpdatedListener() {
@Override
public void onStateUpdate(@NonNull InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED) {
startAlertUpdateDownloaded(mainActivity);
}
}
};
appUpdateManager.registerListener(installStateUpdatedListener);
}
}
private void registerResultLauncher(MainActivity mainActivity) {
activityResultLauncher = mainActivity.registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() != RESULT_OK) {
Log.d("UM", "onActivityResult code: " + result.getResultCode());
}
}
});
}
public void unregisterListener() {
if (appUpdateManager != null && installStateUpdatedListener != null) {
appUpdateManager.unregisterListener(installStateUpdatedListener);
}
}
public void removeInstance() {
if (activityResultLauncher != null) {
activityResultLauncher = null;
}
if (appUpdateManager != null) {
appUpdateManager = null;
}
if (installStateUpdatedListener != null) {
installStateUpdatedListener = null;
}
if (updatesManager != null) {
updatesManager = null;
}
}
}
Looking at report we can see that crash caused by line 68
Fatal Exception: java.lang.NullPointerException: Attempt to invoke
virtual method ‘java.lang.Class java.lang.Object.getClass()’ on a null
object reference
at com.domainName.appName.UpdatesManager$1.onSuccess(UpdatesManager.java:68)
at com.domainName.appName.UpdatesManager$1.onSuccess(UpdatesManager.java:62)
at com.google.android.gms.tasks.zzm.run(com.google.android.gms:play-services-tasks@@18.1.0:1)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8676)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
Line 68 at checkUpdates function
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, activityResultLauncher, AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build());
If I understand right, appUpdateManager object is null here. I suspect something wrong with Activity LifeCycle but can’t find mistake.