mPaaS Deployment
SDK Directory Structure
.
├── bcpkix-jdk15to18-1.69.jar
├── bcprov-jdk15to18-1.69.jar
├── nbs.newlens.android.log-1.0.1.aar
├── nbs.newlens.nativecrash-2.0.7.aar
├── rewriter
│ ├── json-20231013.jar
│ ├── nbs.newlens.so.parser-1.2.1.jar
│ ├── tingyun-ea-agent-android-class-rewriter-2.17.4.jar
│ └── tingyun-ea-agent-android-gradle-plugin-2.17.4.jar
├── shark-1.0.2.jar
├── tingyun-android-base-1.0.2.aar
├── tingyun-basemonitor-1.0.2.aar
├── tingyun-dump-1.0.2.aar
├── tingyun-ea-agent-android-2.17.4.aar
└── tingyun-javaleak-1.0.2.aar
Shell Project (Portal) Dependency Addition
Add the following content to the project-level build.gradle file.
buildscript {
dependencies {
classpath fileTree(dir: 'rewriter', include: ['*.jar'])//Extract the SDK's rewriter folder to the same directory level as the project-level build.gradle file. The jar packages in the rewriter folder are only used during compilation and are not packaged into the APK
}
}
allprojects {
repositories {
flatDir {
dirs 'libs'
}
}
}
Add the following content to the app-level build.gradle file.
apply plugin: 'newlens'
dependencies {
// Copy the SDK to the libs directory of the portal project
// Please replace 'Version' with the specific version number
implementation(name: 'tingyun-ea-agent-android-version', ext: 'aar')
implementation(name: 'nbs.newlens.nativecrash-version', ext: 'aar') // Integrate this package to collect native crashes
implementation(name: 'nbs.newlens.android.log-version', ext: 'aar') // Integrate this package for log Fetch
// To collect OOM data, you need the kotlin-gradle-plugin plugin version 1.3+, and dependencies on androidx.core:core-ktx、androidx.appcompat:appcompat、androidx.lifecycle:lifecycle-process、com.squareup.okio:okio etc.
implementation(name: 'tingyun-javaleak-version.aar', ext: 'aar') // Integrate this package to collect OOM
implementation(name: 'tingyun-basemonitor-version.aar', ext: 'aar') // Integrate this package to collect OOM
implementation(name: 'tingyun-android-base-version', ext: 'aar') // Integrate this package to collect OOM
implementation(name: 'tingyun-dump-version', ext: 'aar') // Integrate this package to collect OOM
implementation files('libs/shark-version.jar') // Integrate this package to collect OOM
implementation files('libs/bcpkix-jdk15to18-version.jar') // Integrate this package to enable national secret encryption
implementation files('libs/bcprov-jdk15to18-version.jar') // Integrate this package to enable national secret encryption
}
Sub-project (Bundle) Dependency Addition
Each bundle needs to configure embedding. Add the following content to the project-level build.gradle file.
buildscript {
dependencies {
classpath fileTree(dir: 'rewriter', include: ['*.jar'])// Extract the SDK's rewriter folder to the same directory level as the project-level build.gradle file. The jar packages in the rewriter folder are only used during compilation and are not packaged into the APK
}
}
Add the following content to the app-level build.gradle file.
apply plugin: 'newlens'
If the plugin needs to call methods in the SDK, add the following content to the app-level build.gradle file.
dependencies {
// Copy tingyun-ea-agent-android-version.aar to the libs directory of the bundle project
compileOnly fileTree(include: ['*.aar'], dir: 'libs')
}
Set Up Application
A custom Application must be used in the portal.
public class MyApp extends com.alipay.mobile.quinox.LauncherApplication {
@Override
public void onCreate() {
super.onCreate();
}
}
Configure the Application in the portal's AndroidMainfest.
<application
android:name=".MyApp"
>
Add SDK
Obtain AppKey
Initialize SDK
Initialize the SDK in the onCreate() method of the Application.
// "Appkey" should be obtained from the Tingyun platform
// "Host" is the "Redirect" server address of the Tingyun platform, no need to add a protocol header
NBSAppAgent.setLicenseKey("AppKey").setRedirectHost("Host").startInApplication(this.getApplicationContext());
The SDK defaults to uploading data via Https. If the server only supports Http, you need to set 'setHttpEnabled(true)'.
NBSAppAgent.setLicenseKey("AppKey").setRedirectHost("Host").setHttpEnabled(true) .startInApplication(this.getApplicationContext());
Permission Configuration Description
For the SDK to interact with the server, 'Internet permission' is a necessary permission.
<!--Necessary permission for interaction with the server-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--Optional permission to obtain the current device's network status and WiFi status, such as: 3G, 4G, 5G, WiFi, recommended to add-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Optional permission to obtain network status on devices with targetSdkVersion 29 or above, Android 10 or above -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Optional permission to use the 'Visual Operation Naming' feature -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
<!-- Optional permission to obtain the current mobile network connection's base station information -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Enable Module Function Switch at First Launch
For compatibility reasons, the SDK only enables all feature modules in debug mode at the first launch, and only the crash module is enabled in non-debug mode. The following interface can be used to enable the SDK's module switches.
- Module Function Switch Interface
/*
The SDK is initialized for the first time and has not yet interacted with the Tingyun platform, so the default module switch only enables the 'Crash Module'. You can customize which modules to enable at the first launch through this interface.
@warning: Call this interface to set the startup options, the SDK's first launch is not controlled by the Tingyun platform switch
*/
NBSAppAgent.setStartOption(int option);
- Code Example
// Call at SDK initialization to enable all feature modules at the first launch
NBSAppAgent.setLicenseKey("AppKey").setRedirectHost("Host").setStartOption(511).start(this.getApplicationContext());// Enable all features at first initialization
Network Instrumentation
The project needs to implement a custom RpcInterceptor and add the corresponding methods of NBSInterceptorHelper from Tingyun in each method.
// mpaas rpc can only add one interceptor, if there is an existing interceptor in the project, you can directly call the corresponding method of NBSInterceptorHelper in the interceptor's callback method.
rpcService.addRpcInterceptor(OperationType.class, new CommonInterceptor());
public class CommonInterceptor implements RpcInterceptor {
private Handler handler = new Handler(Looper.getMainLooper());
@Override
public boolean preHandle(Object o, ThreadLocal<Object> threadLocal, byte[] bytes, Class<?> aClass, Method method, Object[] objects, Annotation annotation, ThreadLocal<Map<String, Object>> threadLocal1) throws RpcException {
RpcInvocationHandler rpcInvocationHandler = (RpcInvocationHandler) Proxy.getInvocationHandler(o);
RpcInvokeContext rpcInvokeContext = rpcInvocationHandler.getRpcInvokeContext();
com.networkbench.agent.impl.instrumentation.NBSInterceptorHelper.preHandle(annotation, rpcInvokeContext);
return true;
}
@Override
public boolean postHandle(Object o, ThreadLocal<Object> threadLocal, byte[] bytes, Class<?> aClass, Method method, Object[] objects, Annotation annotation) throws RpcException {
RpcInvocationHandler rpcInvocationHandler = (RpcInvocationHandler) Proxy.getInvocationHandler(o);
RpcInvokeContext rpcInvokeContext = rpcInvocationHandler.getRpcInvokeContext();
com.networkbench.agent.impl.instrumentation.NBSInterceptorHelper.postHandle(annotation, rpcInvokeContext);
return true;
}
@Override
public boolean exceptionHandle(Object o, ThreadLocal<Object> threadLocal, byte[] bytes, Class<?> aClass, Method method, Object[] objects, final RpcException e, Annotation annotation) throws RpcException {
// The SDK defines some network error codes, such as unknown host 901, connection failure 902, connection timeout 903, SSL error 908, etc. Undefined error codes will not be displayed in the report. You may need to convert the mpaas error codes as needed.
int errorCode = e == null ? 0 : e.getCode();
switch (errorCode) {
case 0 :
errorCode= 900;break;
case 1 :
errorCode= 900;break;
case 2 :
errorCode= 901;break;
case 3 :
errorCode= 908;break;
case 4 :
errorCode= 903;break;
case 5 :
errorCode= 903;break;
case 6 :
errorCode= 900;break;
case 7 :
errorCode= 900;break;
case 8 :
errorCode= 900;break;
case 9 :
errorCode= 902;break;
case 10 :
errorCode= 900;break;
case 13 :
errorCode= 900;break;
case 15 :
errorCode= 902;break;
case 16 :
errorCode= 901;break;
case 18 :
errorCode= 900;break;
}
com.networkbench.agent.impl.instrumentation.NBSInterceptorHelper.exceptionHandle(annotation, errorCode);
return true;
}
}
Embedded WebView Instrumentation
The SDK supports automatic collection of H5 data for methods such as MPNebula.startUrl() and MPNebula.startApp() without additional configuration.
If the project uses an embedded WebView, manual embedding is required.
- Related Interface
/**
* @param h5Page H5Page object
* @param apWebViewClient If there is a custom implementation of APWebViewClient, pass in that object, otherwise pass null
* @param apWebChromeClient If there is a custom implementation of APWebChromeClient, pass in that object, otherwise pass null
*/
NBSNebulaWebViewConfig.configWebView(H5Page h5Page, APWebViewClient apWebViewClient, APWebChromeClient apWebChromeClient);
- Code Example
MPNebula.getH5ViewAsync(this, param, new H5PageReadyListener() {
@Override
public void getH5Page(H5Page h5Page) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
// If there is no custom implementation of APWebViewClient or APWebChromeClient, only pass the h5Page object
NBSNebulaWebViewConfig.configWebView(h5Page, null, null);
mLayout.addView(h5Page.getContentView(), lp);
}
});
Obtain User Identifier
By adding a 'User Identifier', you can search for specific user performance issues on the Tingyun report platform using this identifier.
- Related Interface
// The userIdentifier can contain up to 64 characters, supports Chinese, English, numbers, underscores, but cannot contain spaces or other escape characters
NBSAppAgent.setUserIdentifier(String userIdentifier);
- Code Example
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String userIdentifier = getUserID();
NBSAppAgent.setLicenseKey("AppKey").withLocationServiceEnabled(true).start(this.getApplicationContext());
// The user identifier can be an email address, phone number, or other information that can identify the user's identity, such as: xxx@tingyun.com
NBSAppAgent.setUserIdentifier(userIdentifier);
}
}
Enable National Secret Encryption
The SDK supports sending data using the national secret encryption method.
Note:
National secret encryption only supports Android 6.0 and above. After enabling national secret encryption, the SDK will not collect data on Android 5.x and below.
To enable national secret, you need to integrate bcpkix-jdk15to18-version.jar and bcprov-jdk15to18-version.jar.
The server side also needs to enable national secret encryption functionality simultaneously.
- Related Interface
// isEncryptionRequired defaults to false, set to true to enable national secret encryption
NBSAppAgent.encryptionRequired(boolean isEncryptionRequired)
- Code Example
NBSAppAgent.setLicenseKey("AppKey").setRedirectHost("Host")
.encryptionRequired(true)// Enable national secret encryption
.start(this.getApplicationContext());
Configure Proguard
Add the following content to the proguard configuration file to prevent the SDK from being unusable.
# ProGuard configurationsfor NetworkBench Lens
-keep class com.networkbench.** { *; }
-dontwarn com.networkbench.**
-keepattributes Exceptions, Signature, InnerClasses
# End NetworkBench Lens
If the project uses OkHttp 3, add the following content to proguard.cfg to avoid affecting network metric collection.
-keep class okhttp3.** { *;}
-dontwarn okhttp3.**
If the project enables national secret, add the following content to proguard.cfg to avoid affecting data collection.
-keep class org.bouncycastle.**{ *;}
-dontwarn org.bouncycastle.**
If line number information needs to be retained, add the following content to proguard.cfg.
-keepattributes SourceFile,LineNumberTable
Packaging and Compilation
Package the sub-project bundles first, then package the shell project portal.
Embedding Verification
After embedding is complete, you can check the results of the Tingyun SDK log output through "LogCat" for data collection server verification with the TAG NBSAgent. The standard log output result is as follows:
NBSAgent start
NBSAgent enabled
NBSAgent V “TingYun_Version” //TingYun_Version is the version number of the current SDK
connect success
Appendix (Optional Configuration)
Enable Visual Naming
Enable the visual naming feature to rename 'native pages' and 'operations' for display in the user experience module by selecting within the app.
-
Obtain Scheme。
In the app's 'Settings' under 'Modify Settings', select [URL Scheme].
-
Add scheme configuration to the 'LAUNCHER Activity' in the AndroidMainfest.xml file as shown below:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Add the entire intent-filter block here and ensure there is only one data field -->
<intent-filter>
<data android:scheme="tingyun.xxxx" />
<!-- Replace "tingyun.xxxx" in the scheme with the URL Scheme from the Tingyun report settings page -->
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
<!-- Add the entire intent-filter block here and ensure there is only one data field -->
</activity>