mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Merge pull request #942 from maskaravivek/leaks
Fix Leaks in Nearby activity
This commit is contained in:
commit
955b3f17a4
5 changed files with 103 additions and 104 deletions
|
|
@ -77,6 +77,8 @@ public class CommonsApplication extends Application implements HasActivityInject
|
||||||
private DBOpenHelper dbOpenHelper = null;
|
private DBOpenHelper dbOpenHelper = null;
|
||||||
private NearbyPlaces nearbyPlaces = null;
|
private NearbyPlaces nearbyPlaces = null;
|
||||||
|
|
||||||
|
private RefWatcher refWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This should not be called by ANY application code (other than the magic Android glue)
|
* This should not be called by ANY application code (other than the magic Android glue)
|
||||||
* Use CommonsApplication.getInstance() instead to get the singleton.
|
* Use CommonsApplication.getInstance() instead to get the singleton.
|
||||||
|
|
@ -128,7 +130,9 @@ public class CommonsApplication extends Application implements HasActivityInject
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
setupLeakCanary();
|
if (setupLeakCanary() == RefWatcher.DISABLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Timber.plant(new Timber.DebugTree());
|
Timber.plant(new Timber.DebugTree());
|
||||||
|
|
||||||
|
|
@ -160,6 +164,11 @@ public class CommonsApplication extends Application implements HasActivityInject
|
||||||
return LeakCanary.install(this);
|
return LeakCanary.install(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RefWatcher getRefWatcher(Context context) {
|
||||||
|
CommonsApplication application = (CommonsApplication) context.getApplicationContext();
|
||||||
|
return application.refWatcher;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Account|null
|
* @return Account|null
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import fr.free.nrw.commons.settings.Prefs;
|
||||||
import fr.free.nrw.commons.upload.UploadService;
|
import fr.free.nrw.commons.upload.UploadService;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -156,6 +157,7 @@ public class ContributionsActivity extends AuthenticatedActivity
|
||||||
requestAuthToken();
|
requestAuthToken();
|
||||||
initDrawer();
|
initDrawer();
|
||||||
setTitle(getString(R.string.title_activity_contributions));
|
setTitle(getString(R.string.title_activity_contributions));
|
||||||
|
setUploadCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -255,8 +257,6 @@ public class ContributionsActivity extends AuthenticatedActivity
|
||||||
((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor);
|
((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
setUploadCount();
|
|
||||||
|
|
||||||
contributionsList.clearSyncMessage();
|
contributionsList.clearSyncMessage();
|
||||||
notifyAndMigrateDataSetObservers();
|
notifyAndMigrateDataSetObservers();
|
||||||
}
|
}
|
||||||
|
|
@ -288,8 +288,7 @@ public class ContributionsActivity extends AuthenticatedActivity
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
private void setUploadCount() {
|
private void setUploadCount() {
|
||||||
CommonsApplication app = ((CommonsApplication) getApplication());
|
CommonsApplication app = ((CommonsApplication) getApplication());
|
||||||
compositeDisposable.add(
|
Disposable uploadCountDisposable = mediaWikiApi
|
||||||
mediaWikiApi
|
|
||||||
.getUploadCount(app.getCurrentAccount().name)
|
.getUploadCount(app.getCurrentAccount().name)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -298,8 +297,8 @@ public class ContributionsActivity extends AuthenticatedActivity
|
||||||
.getQuantityString(R.plurals.contributions_subtitle,
|
.getQuantityString(R.plurals.contributions_subtitle,
|
||||||
uploadCount, uploadCount)),
|
uploadCount, uploadCount)),
|
||||||
t -> Timber.e(t, "Fetching upload count failed")
|
t -> Timber.e(t, "Fetching upload count failed")
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
compositeDisposable.add(uploadCountDisposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class LocationServiceManager implements LocationListener {
|
public class LocationServiceManager implements LocationListener {
|
||||||
|
|
@ -16,11 +17,25 @@ public class LocationServiceManager implements LocationListener {
|
||||||
private LatLng latestLocation;
|
private LatLng latestLocation;
|
||||||
private Float latestLocationAccuracy;
|
private Float latestLocationAccuracy;
|
||||||
|
|
||||||
public LocationServiceManager(Context context) {
|
private static LocationServiceManager locationServiceManager;
|
||||||
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
|
||||||
|
private LocationServiceManager() {
|
||||||
|
Context applicationContext = CommonsApplication.getInstance().getApplicationContext();
|
||||||
|
this.locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE);
|
||||||
provider = locationManager.getBestProvider(new Criteria(), true);
|
provider = locationManager.getBestProvider(new Criteria(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LocationServiceManager getInstance() {
|
||||||
|
if (locationServiceManager == null) {
|
||||||
|
locationServiceManager = new LocationServiceManager();
|
||||||
|
}
|
||||||
|
return locationServiceManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isProviderEnabled() {
|
||||||
|
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
public LatLng getLatestLocation() {
|
public LatLng getLatestLocation() {
|
||||||
return latestLocation;
|
return latestLocation;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.LocationManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
@ -37,6 +35,10 @@ import fr.free.nrw.commons.location.LatLng;
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
import fr.free.nrw.commons.utils.UriSerializer;
|
import fr.free.nrw.commons.utils.UriSerializer;
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -50,9 +52,9 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
private LocationServiceManager locationManager;
|
private LocationServiceManager locationManager;
|
||||||
private LatLng curLatLang;
|
private LatLng curLatLang;
|
||||||
private Bundle bundle;
|
private Bundle bundle;
|
||||||
private NearbyAsyncTask nearbyAsyncTask;
|
|
||||||
private SharedPreferences sharedPreferences;
|
private SharedPreferences sharedPreferences;
|
||||||
private NearbyActivityMode viewMode;
|
private NearbyActivityMode viewMode;
|
||||||
|
private Disposable placesDisposable;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
@ -60,6 +62,7 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||||
setContentView(R.layout.activity_nearby);
|
setContentView(R.layout.activity_nearby);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
|
locationManager = LocationServiceManager.getInstance();
|
||||||
checkLocationPermission();
|
checkLocationPermission();
|
||||||
bundle = new Bundle();
|
bundle = new Bundle();
|
||||||
initDrawer();
|
initDrawer();
|
||||||
|
|
@ -105,11 +108,8 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startLookingForNearby() {
|
private void startLookingForNearby() {
|
||||||
locationManager = new LocationServiceManager(this);
|
|
||||||
locationManager.registerLocationManager();
|
|
||||||
curLatLang = locationManager.getLatestLocation();
|
curLatLang = locationManager.getLatestLocation();
|
||||||
nearbyAsyncTask = new NearbyAsyncTask(this);
|
setupPlaceList(getBaseContext());
|
||||||
nearbyAsyncTask.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkLocationPermission() {
|
private void checkLocationPermission() {
|
||||||
|
|
@ -169,9 +169,6 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
startLookingForNearby();
|
startLookingForNearby();
|
||||||
} else {
|
} else {
|
||||||
//If permission not granted, go to page that says Nearby Places cannot be displayed
|
//If permission not granted, go to page that says Nearby Places cannot be displayed
|
||||||
if (nearbyAsyncTask != null) {
|
|
||||||
nearbyAsyncTask.cancel(true);
|
|
||||||
}
|
|
||||||
if (progressBar != null) {
|
if (progressBar != null) {
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
@ -200,8 +197,7 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGps() {
|
private void checkGps() {
|
||||||
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
if (!locationManager.isProviderEnabled()) {
|
||||||
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
|
|
||||||
Timber.d("GPS is not enabled");
|
Timber.d("GPS is not enabled");
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setMessage(R.string.gps_disabled)
|
.setMessage(R.string.gps_disabled)
|
||||||
|
|
@ -231,16 +227,30 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleView() {
|
private void toggleView() {
|
||||||
if (nearbyAsyncTask != null) {
|
|
||||||
if (nearbyAsyncTask.getStatus() == AsyncTask.Status.FINISHED) {
|
|
||||||
if (viewMode.isMap()) {
|
if (viewMode.isMap()) {
|
||||||
setMapFragment();
|
setMapFragment();
|
||||||
} else {
|
} else {
|
||||||
setListFragment();
|
setListFragment();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
sharedPreferences.edit().putBoolean(MAP_LAST_USED_PREFERENCE, viewMode.isMap()).apply();
|
sharedPreferences.edit().putBoolean(MAP_LAST_USED_PREFERENCE, viewMode.isMap()).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
locationManager.registerLocationManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
locationManager.unregisterLocationManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
placesDisposable.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -249,57 +259,23 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
checkGps();
|
checkGps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
if (nearbyAsyncTask != null) {
|
|
||||||
nearbyAsyncTask.cancel(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshView() {
|
private void refreshView() {
|
||||||
curLatLang = locationManager.getLatestLocation();
|
curLatLang = locationManager.getLatestLocation();
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
nearbyAsyncTask = new NearbyAsyncTask(this);
|
setupPlaceList(getBaseContext());
|
||||||
nearbyAsyncTask.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupPlaceList(Context context) {
|
||||||
protected void onDestroy() {
|
placesDisposable = Observable.fromCallable(() -> NearbyController
|
||||||
super.onDestroy();
|
.loadAttractionsFromLocation(curLatLang, CommonsApplication.getInstance()))
|
||||||
if (locationManager != null) {
|
.subscribeOn(Schedulers.io())
|
||||||
locationManager.unregisterLocationManager();
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
.subscribe((result) -> {
|
||||||
}
|
populatePlaces(context, result);
|
||||||
|
});
|
||||||
private class NearbyAsyncTask extends AsyncTask<Void, Integer, List<Place>> {
|
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
private NearbyAsyncTask(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(Integer... values) {
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<Place> doInBackground(Void... params) {
|
|
||||||
return NearbyController
|
|
||||||
.loadAttractionsFromLocation(curLatLang, CommonsApplication.getInstance()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<Place> placeList) {
|
|
||||||
super.onPostExecute(placeList);
|
|
||||||
|
|
||||||
if (isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void populatePlaces(Context context, List<Place> placeList) {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.registerTypeAdapter(Uri.class, new UriSerializer())
|
.registerTypeAdapter(Uri.class, new UriSerializer())
|
||||||
.create();
|
.create();
|
||||||
|
|
@ -308,7 +284,7 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
|
|
||||||
if (placeList.size() == 0) {
|
if (placeList.size() == 0) {
|
||||||
int duration = Toast.LENGTH_SHORT;
|
int duration = Toast.LENGTH_SHORT;
|
||||||
Toast toast = Toast.makeText(mContext, R.string.no_nearby, duration);
|
Toast toast = Toast.makeText(context, R.string.no_nearby, duration);
|
||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -327,7 +303,6 @@ public class NearbyActivity extends NavigationBaseActivity {
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls fragment for map view.
|
* Calls fragment for map view.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import com.squareup.leakcanary.RefWatcher;
|
||||||
|
|
||||||
// This class is automatically discovered by Robolectric
|
// This class is automatically discovered by Robolectric
|
||||||
public class TestCommonsApplication extends CommonsApplication {
|
public class TestCommonsApplication extends CommonsApplication {
|
||||||
@Override protected RefWatcher setupLeakCanary() {
|
@Override
|
||||||
|
protected RefWatcher setupLeakCanary() {
|
||||||
// No leakcanary in unit tests.
|
// No leakcanary in unit tests.
|
||||||
return RefWatcher.DISABLED;
|
return RefWatcher.DISABLED;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue