
使用AppSpector,您可以在同一房间或在另一个大陆上运行的应用程序远程调试。您可以实时衡量应用程序性能,查看数据库内容,日志,网络请求等。这是您一直在寻找的工具。不要将自己限制在简单的日志中。调试不必痛苦!
您要与AppSpector SDK一起使用的每个应用程序都必须通过Web(https://app.appspector.com)或桌面应用在我们的服务上注册。将应用程序导航到应用程序设置并复制API密钥后。
apply plugin : ' com.android.application '
// Add AppSpector maven repository
repositories {
maven { url " https://maven.appspector.com/artifactory/android-sdk " }
}
dependencies {
implementation " com.appspector:android-sdk:1.+ "
}如果您不想在发行版中使用AppSpector SDK时,请使用AppSpector no-op trifact
dependencies {
debugImplementation " com.appspector:android-sdk:1.6.+ "
releaseImplementation( " com.appspector:android-sdk:1.6.+ " ) {
exclude group : ' com.appspector ' , module : ' android-core '
}
} import android . app . Application ;
import com . appspector . sdk . AppSpector ;
public class AmazingApp extends Application {
@ Override
public void onCreate () {
super . onCreate ();
// We recommend to start AppSpector from Application#onCreate method
// You can start all monitors
AppSpector
. build ( this )
. withDefaultMonitors ()
. run ( "API_KEY" );
// Or you can select monitors that you want to use
AppSpector
. build ( this )
. addPerformanceMonitor ()
. addLogMonitor ()
// Next line disables added monitor above. In our case, Log and Performace monitors.
. disableProvidedMonitors () // Disabled monitors can be enabled from Dashboard.
. addHttpMonitor ()
. addScreenshotMonitor ()
. addSQLMonitor ()
// Monitors that were not added to config will be ignored till declared here.
. run ( "API_KEY" );
}
}AppSpector SDK收集和存储用户数据,包括日志,数据库内容和网络流量。所有这些都可能包含敏感数据,因此为了保护您的隐私,我们提供了一个具有E2EE功能的其他模块。它允许您加密从设备或设备发送的所有数据应用程序发送的所有数据应用程序,并确保只能解密它。由于原因,加密会话仅在桌面应用程序中可用。
要使用加密,必须在使用桌面应用程序的应用程序注册期间选择Enable End-To-End encryption选项(以前注册的应用程序无法更新以支持加密)。
之后,您需要将android-sdk-encryption模块添加到依赖项声明中。因此,您的应用程序级build.gradle应该包含下一行:
apply plugin : ' com.android.application '
// Add AppSpector maven repository
repositories {
maven { url " https://maven.appspector.com/artifactory/android-sdk " }
}
dependencies {
implementation " com.appspector:android-sdk:1.+ "
implementation ' com.appspector:android-sdk-encryption:1.+ '
}最后,通过将启用加密放置为SDK配置来启用enableEncryption 。您可以在应用程序设置屏幕上找到的客户Public Key 。
AppSpector
. build ( this )
. withDefaultMonitors ()
. enableEncryption ( "CLIENT_PUBLIC_KEY" )
. run ( "API_KEY" );建立您的项目,看看一切工作!当您的应用程序启动并运行时,您可以访问https://app.appspector.com并连接到您的申请会话。
调用run方法后,SDK启动数据收集和数据传输到Web服务。从那时起,您可以在AppSpector客户端中看到您的会话。
由于我们建议将SDK初始化保留在您应用程序的onCreate()方法中,因此SDK通过调用stopSdk()和startsdk()和startSdk()静态方法提供了帮助您控制应用程序状态的方法。您只能在初始化AppSpector之后才能使用这些方法。
stop()告诉应用程序范围禁用所有数据收集并关闭当前会话。
AppSpector . stopSdk (); startSdk()使用您在初始化时提供的配置再次启动它。
AppSpector . startSdk ();结果将创建新的会话,并且将不会跟踪stop()和start()调用之间的所有活动。
要检查应用程序状态,您可以使用isStarted()方法。
AppSpector . shared (). isStarted ();您可以将自定义名称分配给设备,以轻松在会话列表中找到所需的会话。 AppSpector.METADATA_KEY_DEVICE_NAME metadata
AppSpector
. build ( this )
. withDefaultMonitors ()
. addMetadata ( AppSpector . METADATA_KEY_DEVICE_NAME , "YOUR_DEVICE_NAME" )
. run ( "YOUR_API_KEY" );此外,SDK允许在应用程序寿命期间使用
更改设备名称的setMetadataValue方法
AppSpector . shared (). setMetadataValue ( AppSpector . METADATA_KEY_DEVICE_NAME , "NEW_DEVICE_NAME" );或删除自定义设备名称的removeMetadataValue
AppSpector . shared (). removeMetadataValue ( AppSpector . METADATA_KEY_DEVICE_NAME );对于SQLCipher数据库中的浏览和运行SQL查询,您需要执行几个其他步骤。首先,将sqlcipher-extension模块添加到主SDK模块下的app/build.gradle文件中。因此,看起来像这样:
dependencies {
implementation ' com.appspector:android-sdk:1.+ '
implementation ' com.appspector:sqlcipher-extension:1.+ '
}之后,创建DataBaseConnectionFactory并将其作为addSQLMonitor方法的参数传递。
让我们想象您的项目包含带有“ my_encrypted_db”名称和其他sqlite的SQLCIPHER数据库:
AppSpector
. build ( this )
. withDefaultMonitors ()
. addSQLMonitor ( new SQLiteMonitor . DatabaseConnectionFactory () {
@ NonNull
@ Override
public DatabaseConnection createDatabaseConnection ( @ NonNull Database database ) {
if ( "my_encrypted_db" . equals ( database . name )) {
return new SQLCipherDatabaseConnection ( database , "password" );
}
return new SQLiteDatabaseConnection ( database );
}
})
. run ( "YOUR_API_KEY" );有时,您可能需要调整或完全跳过一些数据应用程序范围收集。
为此,HTTP监视器提供了接口HTTPFilter ,可以将其传递给addHttpMonitor(HTTPFilter)方法。
假设我们想从请求标题中跳过我们的验证令牌。这是此过滤器的示例:
public class TokenFilter implements HTTPFilter {
@ Nullable
@ Override
public HttpRequest filter ( HttpRequest request ) {
if ( request . getHeaders (). containsKey ( "YOUR-AUTH-HEADER" )) {
request . getHeaders (). remove ( "YOUR-AUTH-HEADER" );
}
return request ;
}
@ Nullable
@ Override
public HttpResponse filter ( HttpResponse response ) {
return response ;
}
}SharedPreferences Monitor允许通过使用SharedPreferencesSourceFactory指定要观察的文件。
SharedPreferencesSourceFactory.all()方法。默认情况下,监视器使用此值。SharedPreferencesSourceFactory.excludeFiles("preferences_name")方法,其中“ pereences_name”是忽略的文件的名称。您可以根据需要传递尽可能多的文件名。SharedPreferencesSourceFactory.only("preferences_name")方法,其中“ pereences_name”是要观察的文件名。此方法还可以收到您想要的尽可能多的Argumens。在附录中,监视器允许提供SharedPreferencesMonitor.Filter在发送客户端数据之前删除或修改某些值。
假设您要删除key_1并在文件preferences_name中修改key_2首选项。因此,您的过滤器看起来像这样:
public class SimpleSharedPreferencesFilter implements SharedPreferencesMonitor . Filter {
@ NonNull
@ Override
public Map < String , PreferenceValue > filter ( @ NonNull String fileName , @ NonNull Map < String , PreferenceValue > values ) {
if ( fileName . equals ( "preferences_name" )) {
values . remove ( "key_1" );
if ( values . containsKey ( "key_2" )) {
values . put ( "key_2" , PreferenceValue . stringValue ( "modified value" ));
}
}
return values ;
}
} For applying these customizations, you need to use one of these methods: addSharedPreferenceMonitor(SharedPreferencesMonitor.Filter) , addSharedPreferenceMonitor(SharedPreferencesSourceFactory) , addSharedPreferenceMonitor(SharedPreferencesSourceFactory, SharedPreferencesMonitor.Filter) .
要过滤日志,您需要实现LogMonitor.Filter并将其传递给addLogMonitor(LogMonitor.Filter)方法。
让我们考虑一个示例,我们想更改日志级别以警告所有Word令牌的所有消息:
public class LogFilter implements LogMonitor . Filter {
@ Nullable
@ Override
public LogEvent filter ( LogEvent event ) {
if ( event . message . contains ( "token" )) {
event . level = LogLevel . WARN ;
}
return request ;
}
}让我们向监视器提供创建的填充物:
AppSpector
. build ( this )
. withDefaultMonitors ()
. addHttpMonitor ( new TokenFilter ())
. addSharedPreferenceMonitor ( new SimpleSharedPreferencesFilter ())
. addLogMonitor ( new LogFilter ())
. run ( "YOUR_API_KEY" );有时,您可能需要从代码指向当前会话。假设您要使用碰撞记者中的链接崩溃,将其写入日志或在调试UI中显示。要获取此URL,您必须添加一个会话开始回调:
AppSpector . shared (). setSessionUrlListener ( new SessionUrlListener () {
@ Override
public void onReceived ( @ NonNull String sessionUrl ) {
// Save url for future use...
}
});默认情况下,Appspector SDK处于活动状态,直到该应用程序被Android OS杀死,即使没有剩下的活动。它可能会导致不必要的数据收集和无效应用程序的长时间会议。当应用程序没有启动活动时,我们为禁用数据收集的API。
AppSpector
. build ( this )
. collectDataInBackground ( false ) // Set this flag to disable data collection if no activities left
. withDefaultMonitors ()
. run ( "YOUR_API_KEY" );如果您不想使用Appspector Gradle插件,则可以使用另一种方法来拦截HTTP请求和响应。您可以将AppSpectorOkHttp3Interceptor手动添加到OKHTTPCLIENT(或okhttpclient的旧版本)的OKHTTPCLIENT(或AppSpectorOkHttp2Interceptor )。另外,如果添加了插件,请不要忘记从app/build.gradle文件中删除应用程序启用插件。
new OkHttpClient . Builder ()
. addInterceptor ( new AuthenticationInterceptor ()) // for example, it adds auth token to you request
. addInterceptor ( new AppSpectorOkHttp3Interceptor ()) // it will track your requests and responses
. build ()在当前时刻,SDK为您的代码库中的手动设置提供了API。要在项目中使用它,首先,您需要添加urlconnection-extension gradle依赖性:
dependencies {
implementation ' com.appspector:android-sdk:1.+ '
implementation ' com.appspector:urlconnection-extension:1.+ '
}之后,用urlinstrument.opennection url.openConnection() UrlInstrument.openConnection(url)调用。假设我们有获取Google页面的方法,我们想跟踪此请求:
import java . net . HttpURLConnection ;
import java . net . URL ;
public void getGooglePage () {
HttpURLConnection connection = null ;
try {
connection = ( HttpURLConnection ) new URL ( "https://google.com" ). openConnection ();
if ( connection . getResponseCode () == 200 ) {
//Read data from connection.inputStream
}
} catch ( IOException ex ) {
Log . d ( "UrlConnectionSample" , "Request was failed" , ex );
} finally {
if ( connection != null ) {
connection . disconnect ();
}
}
}SDK集成后,看起来像是这样的:
import com . appspector . sdk . urlconnection . instrumentation . UrlInstrument ;
import java . net . HttpURLConnection ;
import java . net . URL ;
public void getGooglePage () {
HttpURLConnection connection = null ;
try {
connection = ( HttpURLConnection ) UrlInstrument . openConnection ( new URL ( "https://google.com" ));
if ( connection . getResponseCode () == 200 ) {
//Read data from connection.inputStream
}
} catch ( IOException ex ) {
Log . d ( "UrlConnectionSample" , "Request was failed" , ex );
} finally {
if ( connection != null ) {
connection . disconnect ();
}
}
}就是这样!注意:调用disconnect方法对我们很重要。请求完成是一个标记。
如果将木材集成到您的项目中,则可以轻松地将其与Appspector一起使用:
Timber . plant ( new Timber . DebugTree () {
@ Override
void log ( int priority , String tag , @ NotNull String message , Throwable t ) {
Logger . log ( priority , tag , message , t )
}
})AppSpector提供了许多跟踪应用程序中不同活动的监视器:
为您的应用程序中的SQLite数据库提供浏览器。允许跟踪所有查询,显示DB方案和数据库中的数据。您可以在任何DB上发布自定义SQL查询,并立即在浏览器中查看结果。

显示应用程序中的所有HTTP流量。您可以检查任何请求,请参阅请求/响应标题和身体。我们提供XML和JSON Highliting,以提供格式和折叠选项的请求/响应,因此即使是巨大的响应也很容易查看。

显示您的应用程序生成的所有日志。

AppSpector Logger允许您仅将日志消息收集到AppSpector服务中。当您记录一些内部数据巫婆时,这很有用。 AppSpector Logger与android.util.Log类具有相同的API。
Logger . d ( "MyTAG" , "It won't be printed to the Logcat" );大多数应用程序都是位置感知的。测试它需要自己更改位置。在这种情况下,嘲笑位置是一个实时节省的。只需指向地图上的位置,您的应用程序将立即更改其地理上。

显示CPU /内存 /网络 /磁盘 /电池使用情况的实时图。

只需从设备捕获屏幕截图即可。

提供共享流程的浏览器和编辑器。

提供对应用程序内部文件夹的访问。因此,使用此监视器可以下载,删除或上传文件,创建文件夹,然后浏览应用程序的文件夹。

监视器允许您发送想要查看的任何数据。 SDK提供了一个简单的API来发送您的活动。这是一个示例:
CustomEventsSender . send ( new MyCustomEvent ())在示例中, MyCustomEvent类实现CustomEventPayload界面,如下所示:
public class MyCustomEvent implements CustomEventPayload {
@ NonNull
@ Override
public String getName () {
return "Custom Event" ;
}
@ NonNull
@ Override
public String getCategory () {
return "Application" ;
}
@ NonNull
@ Override
public Map < String , Object > getPayload () {
final Map < String , Object > payload = new HashMap <>();
payload . put ( "sampleDate" , new Date ());
payload . put ( "sampleBool" , false );
payload . put ( "sampleInt" , 42 );
payload . put ( "sampleString" , "Test" );
return payload ;
}
}监视器提供了一个机会,可以从Appspector仪表板远程触发您的代码。触发的代码应包裹在AppSpector的CommandCallback中,并注册到SDK。该命令允许您将params传递到代码并声明结果类型。
假设您需要用指定的文本显示吐司并返回int值。
这是您命令的声明,需要消息参数并具有整数结果。
@ Command ( value = "Show message" , category = "Application" )
public class ShowToastCommand extends BaseCommand < Integer > {
@ Argument ( isRequired = true )
public String message ;
}这是您命令的注册和CommandCallback的实现。
AppSpector . shared (). commands (). register ( ShowToastCommand . class , new CommandCallback < Integer , ShowToastCommand >() {
@ Override
public void exec ( @ NonNull final ShowToastCommand command , @ NonNull final Responder < Integer > responder ) {
new Handler ( Looper . getMainLooper ()). post ( new Runnable () {
@ Override
public void run () {
Toast . makeText ( getContext (), command . message , Toast . LENGTH_SHORT ). show ();
responder . ok ( 42 );
}
});
}
});此命令将出现在Application类别下,并将在仪表板上Show message名称。您可以使用自己的类别在仪表板上分组命令。
仅在运行SDK后才能注册命令。
让我们知道您想什么或想改进什么:[email protected]。
加入我们的Slack,讨论设置过程和功能