Merge branch 'npe_135' into 'master'

Do not manually call onChange() (fix NPE)

If the AppDetails activity has been destroyed by the system during an
application installation/remove, it is recreated once it should be
displayed again (this behavior can be forced by enabling "Don't keep
activities" in Android developer options).

In onCreate(), it passes its instance of myInstallerCallback to an
Installer. In onActivityResult() (which is called before onResume()),
this installer calls a method (onSuccess() or onError()) on this
callback. The implementation of these methods (the anonymous inner class
assigned to myInstallerCallback) dereference myAppObserver, which is
still null, because it will be initialized in onResume(), so a
NullPointerException is thrown.

However, the problem is not only that myAppObserver.onChange() is called
when myAppObserver is null, but that it should not be called manually at
all: it is a ContentObserver, so it is automatically called when
registered to the content resolver. As a consequence, this callback was
called twice.

Removing these calls fix both problems.

Should fix issue #135
https://gitlab.com/fdroid/fdroidclient/issues/135

See merge request !58
This commit is contained in:
Peter Serwylo 2015-03-13 12:37:34 +00:00
commit d7c19c76c9

View File

@ -144,18 +144,9 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
@Override
public void onChange(boolean selfChange, Uri uri) {
onChange();
onAppChanged();
}
public void onChange() {
if (!reset(app.id)) {
AppDetails.this.finish();
return;
}
refreshApkList();
supportInvalidateOptionsMenu();
}
}
class ApkListAdapter extends ArrayAdapter<Apk> {
@ -468,15 +459,19 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
private String mInstalledSigID;
@Override
protected void onResume() {
super.onResume();
protected void onStart() {
super.onStart();
// register observer to know when install status changes
myAppObserver = new AppObserver(new Handler());
getContentResolver().registerContentObserver(
AppProvider.getContentUri(app.id),
true,
myAppObserver);
}
@Override
protected void onResume() {
super.onResume();
if (downloadHandler != null) {
if (downloadHandler.isComplete()) {
downloadCompleteInstallApk();
@ -521,11 +516,14 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
}
protected void onStop() {
super.onStop();
getContentResolver().unregisterContentObserver(myAppObserver);
}
@Override
protected void onPause() {
if (myAppObserver != null) {
getContentResolver().unregisterContentObserver(myAppObserver);
}
super.onPause();
if (app != null && (app.ignoreAllUpdates != startingIgnoreAll
|| app.ignoreThisUpdate != startingIgnoreThis)) {
Log.d(TAG, "Updating 'ignore updates', as it has changed since we started the activity...");
@ -537,8 +535,16 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
removeProgressDialog();
}
super.onPause();
private void onAppChanged() {
if (!reset(app.id)) {
AppDetails.this.finish();
return;
}
refreshApkList();
supportInvalidateOptionsMenu();
}
public void setIgnoreUpdates(String appId, boolean ignoreAll, int ignoreVersionCode) {
@ -924,7 +930,7 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
setSupportProgressBarIndeterminateVisibility(false);
myAppObserver.onChange();
onAppChanged();
}
});
}
@ -936,7 +942,7 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
@Override
public void run() {
setSupportProgressBarIndeterminateVisibility(false);
myAppObserver.onChange();
onAppChanged();
}
});
} else {
@ -944,7 +950,7 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
@Override
public void run() {
setSupportProgressBarIndeterminateVisibility(false);
myAppObserver.onChange();
onAppChanged();
Log.e(TAG, "Installer aborted with errorCode: " + errorCode);