Last active
February 2, 2016 11:40
-
-
Save pabloogc/a131d5c2a8acbf2f9321 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.