Skip to content

Instantly share code, notes, and snippets.

@pabloogc
Last active February 2, 2016 11:40
Show Gist options
  • Save pabloogc/a131d5c2a8acbf2f9321 to your computer and use it in GitHub Desktop.
Save pabloogc/a131d5c2a8acbf2f9321 to your computer and use it in GitHub Desktop.
import java.lang.ref.WeakReference;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public abstract class WeakCallback<T, C> implements Callback<T> {
private final WeakReference<C> context;
public WeakCallback(C context) {
this.context = new WeakReference<>(context);
if (getClass().isAnonymousClass()) {
if (getClass().getEnclosingMethod() != null
&& !Modifier.isStatic(getClass().getEnclosingMethod().getModifiers()))
throw new IllegalStateException("Leaking! Callback is anonymous but method is not static");
} else {
if (getClass().getEnclosingClass() != null
&& !Modifier.isStatic(getClass().getModifiers())) {
throw new IllegalStateException("Leaking! Callback is an inner class but not static");
}
}
}
@Override public final void success(T t, Response response) {
C c = context.get();
if (c != null) {
weakSuccess(c, t, response);
}
}
@Override public final void failure(RetrofitError error) {
C c = context.get();
if (c != null) {
weakFailure(c, error);
}
}
public abstract void weakSuccess(C c, T t, Response response);
public abstract void weakFailure(C c, RetrofitError error);
}
//////////////////////////////////////////
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.ingeniolabs.teamtemplate.view.WeakCallback;
import java.util.List;
import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;
import retrofit.http.GET;
import retrofit.http.Path;
public class MainActivity extends AppCompatActivity {
public static final String API_URL = "https://api.github.com";
public static class Contributor {
public final String login;
public final int contributions;
public Contributor(String login, int contributions) {
this.login = login;
this.contributions = contributions;
}
}
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors") void contributors(
@Path("owner") String owner,
@Path("repo") String repo,
Callback<List<Contributor>> callback);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RestAdapter retrofit = new RestAdapter.Builder()
.setEndpoint(API_URL)
.build();
// Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.class);
github.contributors("square", "retrofit", new GithubCallback(this));
}
private static WeakCallback<List<Contributor>, MainActivity> getGithubCallback(MainActivity c) {
return new WeakCallback<List<Contributor>, MainActivity>(c) {
@Override
public void weakSuccess(MainActivity mainActivity, List<Contributor> contributors, Response response) {
}
@Override public void weakFailure(MainActivity mainActivity, RetrofitError error) {
}
};
}
private static class GithubCallback extends WeakCallback<List<Contributor>, MainActivity> {
public GithubCallback(MainActivity context) {
super(context);
}
@Override
public void weakSuccess(MainActivity mainActivity, List<Contributor> contributors, Response response) {
}
@Override
public void weakFailure(MainActivity mainActivity, RetrofitError error) {
}
}
}
@rallat
Copy link

rallat commented Sep 28, 2015

Good approach to weak retrofit callbacks. However, this uses reflection for each Callback, which could produce a perf problem. I will recommend you to do the "leak check" only when the app is running a debug build, but not in a release build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment