AppGallery Connect(简称AGC)性能管理(Application Performance Management,简称APM)服务提供分钟级应用性能监控能力,依据APM SDK,可以实现零代码快速集成,您能够在AGC查看和分析APM收集到的应用性能数据,从而全面了解所开发应用的性能特点,快速精准修复应用存在的性能问题,持续提升应用的用户体验。
在本次Codelab中,您将建立一个能够集成APM 的应用,另外通过手动触发网络请求事件,以测试APM服务能否正常监控检测网络性能,同时了解如何查看和分析应用性能问题。
集成AGC APM,需要完成以下准备工作
具体操作,请按照《AppGallery Connect集成准备》中详细说明来完成。
buildscript {
repositories {
// Add the maven repository
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
// To benefit from the latest APM feaures, update your Android Gradle Plugin
// dependency to at least v3.5.3
classpath 'com.android.tools.build:gradle:3.5.3'
// Add agc plugin dependence
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
// Add the dependency for the APM plugin
classpath 'com.huawei.agconnect:agconnect-apms-plugin:1.4.1.305'
}
}
apply plugin: 'com.android.application'
// Apply the AGC plugin
apply plugin: 'com.huawei.agconnect'
// Apply the APM plugin
apply plugin: 'com.huawei.agconnect.apms'
dependencies {
//..
}
针对Android Studio开发环境,开发前需集成APM SDK到您的Android Studio项目中。
dependencies {
// Add APM SDK library dependency
implementation 'com.huawei.agconnect:agconnect-apms:1.4.1.305'
}
-keep class com.huawei.agconnect.apms.**{*;}
-dontwarn com.huawei.agconnect.apms.**
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
-keep interface com.huawei.hms.analytics.type.HAEventType{*;}
-keep interface com.huawei.hms.analytics.type.HAParamType{*;}
-keepattributes Exceptions, Signature, InnerClasses, LineNumberTable
本章Codelab中您可以在Android Studio工程中创建一个布局页面,参照下图进行UI设计,新增六个按钮。一个按钮点击后可触发网络监控事件,另外两个按钮点击后可控制是否收集APM性能数据。剩下三个按钮上报自定义事件。
本章Codelab中您可以手动触发一次网络请求,然后在APM性能管理台上查看网络性能指标是否正常(应用启动和应用屏幕事件在应用启动时,自动上报),详细步骤如下:
static private String URL = "https://developer.huawei.com/consumer/cn/";
static private MediaType MEDIATYPE = MediaType.parse("text/x-markdown; charset=utf-8");
static private String REQUESTBODY = "apms http request test";
static public void oneRequest() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.post(RequestBody.create(MEDIATYPE, REQUESTBODY))
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("apmsAndroidDemo", "onFailure: " + e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("apmsAndroidDemo", "onResponse: Success");
}
});
}
Button sendNetworkRequestBtn = findViewById(R.id.btn_network);
sendNetworkRequestBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("apmsAndroidDemo", "send network request.");
HttpUtil.oneRequest();
}
});
本章Codelab中您可以手动触发一次自定义指标上报,然后在APM性能管理台上查看自定义性能指标是否正常。
在应用Activity布局文件中创建三个按钮,描述分为"Send Custom Event"、"Send Custom Event By annotation"和"Send Custom Network Event",分别为通过API上报自定义事件、通过注解上报自定义和通过API上报自定义网络事件。
findViewById(R.id.custom_normal_event).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("apmsAndroidDemo", "send a custom event");
sendCustomEvent();
}
});
// define custom event by code
public void sendCustomEvent() {
CustomTrace customTrace = APMS.getInstance().createCustomTrace("自定义事件1");
customTrace.start();
// code you want trace
businessLogicStart(customTrace);
businessLogicEnd(customTrace);
customTrace.stop();
}
public void businessLogicStart(CustomTrace customTrace) {
customTrace.putMeasure("处理次数", 0);
for (int i = 0; i < 5; i++) {
customTrace.incrementMeasure("处理次数", 1);
}
}
public void businessLogicEnd(CustomTrace customTrace) {
customTrace.putProperty("处理结果", "成功");
customTrace.putProperty("状态", "正常");
}
findViewById(R.id.custom_normal_event_by_annotation).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("apmsAndroidDemo", "send a custom event by annotation");
sendCustomEventByAnnotation();
}
});
private void sendCustomEventByAnnotation() {
customEventHandle();
}
// define custom event by annotation
@AddCustomTrace(name = "自定义事件2")
public void customEventHandle() {
}
findViewById(R.id.custom_network_event).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("apmsAndroidDemo", "send a custom network event");
new Thread(new Runnable() {
@Override
public void run() {
HttpUtil.customNetworkEvent();
}
}).start();
}
});
static private String URL = "https://developer.huawei.com/consumer/cn/";
static private MediaType MEDIATYPE = MediaType.parse("text/x-markdown; charset=utf-8");
static private String REQUESTBODY = "apms http request test";
static public void customNetworkEvent() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.post(RequestBody.create(MEDIATYPE, REQUESTBODY))
.build();
// define custom network event
NetworkMeasure networkMeasure = APMS.getInstance().createNetworkMeasure(URL, "POST");
networkMeasure.setBytesSent(request.headers().byteCount());
long bytesRecive = 0L;
networkMeasure.start();
try {
Response response = okHttpClient.newCall(request).execute();
networkMeasure.setStatusCode(response.code());
if (response.body() != null) {
networkMeasure.setBytesReceived(response.body().contentLength());
networkMeasure.setContentType(Objects.requireNonNull(response.body().contentType()).toString());
bytesRecive = dealResponseBody(response.body());
response.body().close();
}
networkMeasure.putProperty("传输字节", String.valueOf(bytesRecive));
networkMeasure.stop();
} catch (IOException e) {
networkMeasure.setStatusCode(0);
classErrorMessage(networkMeasure, e);
networkMeasure.putProperty("错误信息", e.getMessage());
networkMeasure.putProperty("传输字节", String.valueOf(bytesRecive));
networkMeasure.stop();
}
}
private static void classErrorMessage(NetworkMeasure networkMeasure, Exception e) {
if (e instanceof UnknownHostException) {
networkMeasure.putProperty("错误信息", "DNS解析失败");
}
}
private static long dealResponseBody(ResponseBody body) throws IOException {
InputStream inputStream = body.byteStream();
byte[] result = new byte[1000];
long len = 0;
long readBytes = 0;
while ((len = inputStream.read(result)) != -1) {
readBytes += len;
}
return readBytes;
}
本章Codelab中您可以手动触发一次应用ANR并上报,然后在APM性能管理台上查看ANR数据是否正常。
public void initAnrTestButton() {
findViewById(R.id.anr_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("apmsAndroidDemo", "trigger anr");
anrTestEnable = true;
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (anrTestEnable) {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (anrTestEnable) {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return super.dispatchTouchEvent(ev);
}
findViewById(R.id.enable_apms_on).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
APMS.getInstance().enableCollection(true);
}
});
findViewById(R.id.enable_apms_off).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
APMS.getInstance().enableCollection(false);
}
});
findViewById(R.id.enable_apms_on).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
APMS.getInstance().enableAnrMonitor(true);
}
});
findViewById(R.id.enable_apms_off).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
APMS.getInstance().enableAnrMonitor(false);
}
});
祝贺您,您已经成功地构建了您的第一个集成AGC APM的应用程序,并学到了如何在APM性能管理台查看和分析应用性能数据。
AGC APM的相关API介绍请参见API索引。
本Codelab中所用demo源码下载地址如下: