Forked from pyricau/LeakSlackUploadService.java
Last active
October 27, 2016 02:03
-
-
Save zhEdward/e3c18f73cc7e55f6069a8c6c85ad9052 to your computer and use it in GitHub Desktop.
使用leakCanary 在debug的时候 进行 leak heapdump 日志收集(fork 的例子 UploadService主要使用 Slack API+retrofit2 机制上传)
This file contains hidden or 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
<?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> |
This file contains hidden or 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
//更多详情 请访问: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; | |
} | |
} |
This file contains hidden or 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 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