Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Sending Leak Traces to a Slack Channel using Retrofit2
import com.squareup.leakcanary.AnalysisResult;
import com.squareup.leakcanary.DisplayLeakService;
import com.squareup.leakcanary.HeapDump;
import android.util.Log;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Query;
//Service to upload memory leaks to slack. Inspired by
//adopted to use Retrofit2
public final class LeakSlackUploadService extends DisplayLeakService
implements Callback<LeakSlackUploadService.UploadFileResponse> {
private SlackApi slackApi;
public void onCreate() {
slackApi = new Retrofit.Builder()
.build() //
protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
Log.e(TAG, "afterDefaultHandling " + leakInfo);
if (!result.leakFound || result.excludedLeak) {
Log.e(TAG, "!result.leakFound || result.excludedLeak");
String name = classSimpleName(result.className);
if (!heapDump.referenceName.equals("")) {
name += "(" + heapDump.referenceName + ")";
String title = name + " has leaked5";
String initialComment = leakInfo.substring(0, leakInfo.indexOf("Details:", 0));
RequestBody file = RequestBody
.create(MediaType.parse("multipart/form-data"), heapDump.heapDumpFile);
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", heapDump.heapDumpFile.getName(), file);
final Call<UploadFileResponse> call = slackApi.uploadFile(SlackApi.TOKEN,
heapDump.heapDumpFile.getName(), title, initialComment,
public void onResponse(Call<UploadFileResponse> call,
Response<UploadFileResponse> response) {
Log.d(TAG, response.body().toString());
public void onFailure(Call<UploadFileResponse> call, Throwable t) {
Log.d(TAG, t.getLocalizedMessage());
/** See for documentation. */
public interface SlackApi {
Call<UploadFileResponse> uploadFile(
@Query("token") String token,
@Part MultipartBody.Part file, @Query("filetype") String filetype,
@Query("filename") String filename, @Query("title") String title,
@Query("initial_comment") String initialComment,
@Query("channels") String channels);
public static class UploadFileResponse {
boolean ok;
String error;
public String toString() {
return "UploadFileResponse{" +
"ok=" + ok +
", error='" + error + '\'' +
private static final String TAG = "LeakListenerService";
private static String classSimpleName(String className) {
int separator = className.lastIndexOf('.');
return separator == -1 ? className : className.substring(separator + 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment