Volley request leaks across activity/fragment boundaries should no longer be able to occur.
Also, the singleton allows contexts to be cleaned up instead of holding onto a dead reference.
This commit is contained in:
parent
46fe328967
commit
c1d4bdbdfb
8 changed files with 60 additions and 11 deletions
|
@ -31,7 +31,6 @@ import android.util.TypedValue;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.volley.AuthFailureError;
|
import com.android.volley.AuthFailureError;
|
||||||
|
@ -51,7 +50,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class AccountActivity extends BaseActivity {
|
public class AccountActivity extends BaseActivity {
|
||||||
private static final String TAG = "AccountActivity"; // logging tag
|
private static final String TAG = "AccountActivity"; // Volley request tag and logging tag
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
private String accessToken;
|
private String accessToken;
|
||||||
|
@ -121,6 +120,12 @@ public class AccountActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(this).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
private void obtainAccount() {
|
private void obtainAccount() {
|
||||||
String endpoint = String.format(getString(R.string.endpoint_accounts), accountId);
|
String endpoint = String.format(getString(R.string.endpoint_accounts), accountId);
|
||||||
String url = "https://" + domain + endpoint;
|
String url = "https://" + domain + endpoint;
|
||||||
|
@ -151,6 +156,7 @@ public class AccountActivity extends BaseActivity {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +247,7 @@ public class AccountActivity extends BaseActivity {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +308,7 @@ public class AccountActivity extends BaseActivity {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ import java.util.Map;
|
||||||
|
|
||||||
public class AccountFragment extends Fragment implements AccountActionListener,
|
public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
FooterActionListener {
|
FooterActionListener {
|
||||||
private static final String TAG = "Account"; // logging tag
|
private static final String TAG = "Account"; // logging tag and Volley request tag
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
FOLLOWS,
|
FOLLOWS,
|
||||||
|
@ -94,6 +94,12 @@ public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
accessToken = preferences.getString("accessToken", null);
|
accessToken = preferences.getString("accessToken", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(getContext()).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@ -211,6 +217,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +307,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class MainActivity extends BaseActivity {
|
public class MainActivity extends BaseActivity {
|
||||||
private static final String TAG = "MainActivity"; // logging tag
|
private static final String TAG = "MainActivity"; // logging tag and Volley request tag
|
||||||
|
|
||||||
private AlarmManager alarmManager;
|
private AlarmManager alarmManager;
|
||||||
private PendingIntent serviceAlarmIntent;
|
private PendingIntent serviceAlarmIntent;
|
||||||
|
@ -141,6 +141,7 @@ public class MainActivity extends BaseActivity {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ import java.util.Map;
|
||||||
|
|
||||||
public class NotificationsFragment extends SFragment implements
|
public class NotificationsFragment extends SFragment implements
|
||||||
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
||||||
private static final String TAG = "Notifications"; // logging tag
|
private static final String TAG = "Notifications"; // logging tag and Volley request tag
|
||||||
|
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
|
@ -58,6 +58,12 @@ public class NotificationsFragment extends SFragment implements
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(getContext()).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
|
@ -157,6 +163,7 @@ public class NotificationsFragment extends SFragment implements
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,18 @@ import java.util.Map;
|
||||||
|
|
||||||
public class PullNotificationService extends IntentService {
|
public class PullNotificationService extends IntentService {
|
||||||
private static final int NOTIFY_ID = 6; // This is an arbitrary number.
|
private static final int NOTIFY_ID = 6; // This is an arbitrary number.
|
||||||
private static final String TAG = "PullNotifications";
|
private static final String TAG = "PullNotifications"; // logging tag and Volley request tag
|
||||||
|
|
||||||
public PullNotificationService() {
|
public PullNotificationService() {
|
||||||
super("Tusky Pull Notification Service");
|
super("Tusky Pull Notification Service");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(this).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHandleIntent(Intent intent) {
|
protected void onHandleIntent(Intent intent) {
|
||||||
SharedPreferences preferences = getSharedPreferences(
|
SharedPreferences preferences = getSharedPreferences(
|
||||||
|
@ -94,6 +100,7 @@ public class PullNotificationService extends IntentService {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
VolleySingleton.getInstance(this).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ import java.util.Map;
|
||||||
* overlap functionality. So, I'm momentarily leaving it and hopefully working on those will clear
|
* overlap functionality. So, I'm momentarily leaving it and hopefully working on those will clear
|
||||||
* up what needs to be where. */
|
* up what needs to be where. */
|
||||||
public class SFragment extends Fragment {
|
public class SFragment extends Fragment {
|
||||||
private static final String TAG = "SFragment"; // logging tag
|
private static final String TAG = "SFragment"; // logging tag and Volley request tag
|
||||||
|
|
||||||
protected String domain;
|
protected String domain;
|
||||||
protected String accessToken;
|
protected String accessToken;
|
||||||
|
@ -66,6 +66,12 @@ public class SFragment extends Fragment {
|
||||||
loggedInUsername = preferences.getString("loggedInAccountUsername", null);
|
loggedInUsername = preferences.getString("loggedInAccountUsername", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(getContext()).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
protected void sendRequest(
|
protected void sendRequest(
|
||||||
int method, String endpoint, JSONObject parameters,
|
int method, String endpoint, JSONObject parameters,
|
||||||
@Nullable Response.Listener<JSONObject> responseListener) {
|
@Nullable Response.Listener<JSONObject> responseListener) {
|
||||||
|
@ -92,6 +98,7 @@ public class SFragment extends Fragment {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import java.util.Map;
|
||||||
|
|
||||||
public class TimelineFragment extends SFragment implements
|
public class TimelineFragment extends SFragment implements
|
||||||
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
SwipeRefreshLayout.OnRefreshListener, StatusActionListener, FooterActionListener {
|
||||||
private static final String TAG = "Timeline"; // logging tag
|
private static final String TAG = "Timeline"; // logging tag and Volley request tag
|
||||||
|
|
||||||
public enum Kind {
|
public enum Kind {
|
||||||
HOME,
|
HOME,
|
||||||
|
@ -78,6 +78,12 @@ public class TimelineFragment extends SFragment implements
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
VolleySingleton.getInstance(getContext()).cancelAll(TAG);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
@ -221,6 +227,7 @@ public class TimelineFragment extends SFragment implements
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
request.setTag(TAG);
|
||||||
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,18 @@ import com.android.volley.RequestQueue;
|
||||||
import com.android.volley.toolbox.ImageLoader;
|
import com.android.volley.toolbox.ImageLoader;
|
||||||
import com.android.volley.toolbox.Volley;
|
import com.android.volley.toolbox.Volley;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class VolleySingleton {
|
public class VolleySingleton {
|
||||||
private static VolleySingleton instance;
|
private static VolleySingleton instance;
|
||||||
private RequestQueue requestQueue;
|
private RequestQueue requestQueue;
|
||||||
private ImageLoader imageLoader;
|
private ImageLoader imageLoader;
|
||||||
private static Context context;
|
/* This is a weak reference to account for the case where it might be held onto beyond the
|
||||||
|
* lifetime of the Activity/Fragment/Service, so it can be cleaned up. */
|
||||||
|
private static WeakReference<Context> context;
|
||||||
|
|
||||||
private VolleySingleton(Context context) {
|
private VolleySingleton(Context context) {
|
||||||
VolleySingleton.context = context;
|
VolleySingleton.context = new WeakReference<>(context);
|
||||||
requestQueue = getRequestQueue();
|
requestQueue = getRequestQueue();
|
||||||
imageLoader = new ImageLoader(requestQueue,
|
imageLoader = new ImageLoader(requestQueue,
|
||||||
new ImageLoader.ImageCache() {
|
new ImageLoader.ImageCache() {
|
||||||
|
@ -60,7 +64,7 @@ public class VolleySingleton {
|
||||||
if (requestQueue == null) {
|
if (requestQueue == null) {
|
||||||
/* getApplicationContext() is key, it keeps you from leaking the
|
/* getApplicationContext() is key, it keeps you from leaking the
|
||||||
* Activity or BroadcastReceiver if someone passes one in. */
|
* Activity or BroadcastReceiver if someone passes one in. */
|
||||||
requestQueue= Volley.newRequestQueue(context.getApplicationContext());
|
requestQueue= Volley.newRequestQueue(context.get().getApplicationContext());
|
||||||
}
|
}
|
||||||
return requestQueue;
|
return requestQueue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue