Skip to content

Instantly share code, notes, and snippets.

@zhEdward
Forked from pyricau/LeakSlackUploadService.java
Last active October 27, 2016 02:03
Show Gist options
  • Save zhEdward/e3c18f73cc7e55f6069a8c6c85ad9052 to your computer and use it in GitHub Desktop.
Save zhEdward/e3c18f73cc7e55f6069a8c6c85ad9052 to your computer and use it in GitHub Desktop.
使用leakCanary 在debug的时候 进行 leak heapdump 日志收集(fork 的例子 UploadService主要使用 Slack API+retrofit2 机制上传)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
>
<application android:name="com.example.DebugExampleApplication">
·····
<!--把自定义的 service 写入配置清单 这一点非常重要-->
<service android:name="com.example.LeakSlackUploadService" />
</application>
</manifest>
//更多详情 请访问:https://github.com/square/leakcanary/wiki/Customizing-LeakCanary
public class SquareDebugApplication extends Application {
private RefWatcher refWatcher;
@Override
public void onCreate() {
super.onCreate();
//用于内存泄漏检测工具 对外发布请屏蔽
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
//install 方法默认开启 对activity的 泄漏检测,Fragment的需要自行开启
//LeakCanary.install(this);
refWatcher=installLeakCanary();
}
@Override protected RefWatcher installLeakCanary() {
// 官方的方法在 1.4+ 之后没有找到相关api
//return LeakCanary.install(app, LeakSlackUploadService.class);
// test in v1.4
ExcludedRefs excludedRefs = AndroidExcludedRefs.createAppDefaults()
.instanceField("com.example.ExampleClass", "exampleField")
.build();
RefWatcher refWatcher =LeakCanary.install(this,LeakSlackUploadService.class,excludedRefs);
return refWatcher;
//需要注意 只能在Debug模式下 ,Release版本没有对应的api可以提供调用
//RefWatcher.DISABLED;
}
/**
* 监听fragment的内存泄漏 on{@link Fragment#onDestroy()} use
* {@link App#getRefWatcher(Context).install(this)}
*
* @param context
*
* @return
*/
public static RefWatcher getRefWatcher(Context context) {
App application = (App) context.getApplicationContext();
return application.refWatcher;
}
}
import android.util.Log;
import com.squareup.leakcanary.AnalysisResult;
import com.squareup.leakcanary.DisplayLeakService;
import com.squareup.leakcanary.HeapDump;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.http.Multipart;
import retrofit.http.POST;
import retrofit.http.Part;
import retrofit.mime.TypedFile;
public final class LeakSlackUploadService extends DisplayLeakService {
/** See https://api.slack.com/ for documentation. */
public interface SlackApi {
String TOKEN = "xoxp-SOME-USER-TOKEN";
String MEMORY_LEAK_CHANNEL = "SOME-CHANNEL-TOKEN";
@Multipart @POST("/api/files.upload") UploadFileResponse uploadFile(@Part("token") String token,
@Part("file") TypedFile file, @Part("filetype") String filetype,
@Part("filename") String filename, @Part("title") String title,
@Part("initial_comment") String initialComment, @Part("channels") String channels);
}
public static class UploadFileResponse {
boolean ok;
String error;
@Override 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);
}
private SlackApi slackApi;
@Override public void onCreate() {
super.onCreate();
slackApi = new RestAdapter.Builder() //
.setEndpoint("https://slack.com") //
.build() //
.create(SlackApi.class);
}
@Override
protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
if (!result.leakFound || result.excludedLeak) {
return;
}
String name = classSimpleName(result.className);
if (!heapDump.referenceName.equals("")) {
name += "(" + heapDump.referenceName + ")";
}
String title = name + " has leaked";
String initialComment = leakInfo;
//这里需要自行改为 上传 heapDump.heapDumpFile 和 leakInfo 到 公司自己的服务器(文件流)
// try {
// slackApi.uploadFile(SlackApi.TOKEN,
// new TypedFile("application/octet-stream", heapDump.heapDumpFile), null,
// heapDump.heapDumpFile.getName(), title, initialComment, SlackApi.MEMORY_LEAK_CHANNEL);
// } catch (RetrofitError e) {
// Log.e(TAG, "Error when uploading heap dump", e);
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment