INTERNAL SETTINGS APPSimilar to U+2020 Sample app
Display build / device information
Change endpoint (restart process with)
Show logs ( )
Allow easy bug report capturing( )
Enable/Disable Takt / Stetho / Scalpel /Madge...
JakeWharton/ProcessPhoenix
pedrovgs/Lynx
mattprecious/telescope
DROIDCON VIENNA APPLICATIONhttps://github.com/Nilhcem/droidconat-2016
FRAME RATE
build.gradle:
MyApplication.java:
https://github.com/wasabeef/Takt
compile 'jp.wasabeef:takt:1.0.2'
public class MyApplication extends Application {
@Override public void onCreate() {
super.onCreate();
Takt.stock(this).play();
}
}
HUGOhttps://github.com/JakeWharton/hugo
Prefix classes/methods with:
@DebugLog
Result:
DroidconApp V ⇢ onCreate() V ⇢ initGraph() V ⇠ initGraph [13ms] V ⇢ initLogger() V ⇠ initLogger [1ms] V ⇠ onCreate [73ms]
PIDCAThttps://github.com/JakeWharton/pidcat
$ pidcat com.nilhcem.droidconat
ANDROIDDEVMETRICS
build.gradle:
MyApplication.java:
https://github.com/frogermcs/AndroidDevMetrics
apply plugin: 'com.frogermcs.androiddevmetrics'
public class MyApplication extends Application {
@Override public void onCreate() {
super.onCreate();
AndroidDevMetrics.initWith(this);
}
}
SONARQUBEDockerfile:
FROM java:8
MAINTAINER Nilhcem
RUN DEBIAN_FRONTEND=noninteractive apt update
RUN DEBIAN_FRONTEND=noninteractive apt install -y wget unzip
RUN wget -q https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-6.0.zip
RUN unzip -qq sonarqube-6.0.zip -d /opt/
RUN rm sonarqube-6.0.zip
EXPOSE 9000
CMD ["/opt/sonarqube-6.0/bin/linux-x86-64/sonar.sh", "console"]
Then launch:
$ docker build -t nilhcem/sonarqube .$ docker run -p 9000:9000 -d nilhcem/sonarqube
SONARQUBE GRADLE CONFIGURATIONbuild.gradle:
apply plugin: 'org.sonarqube'
sonarqube { properties { def appProject = project(':app') def appProjectBuildDir = appProject.buildDir
property 'sonar.projectKey', 'droidconat' property 'sonar.projectName', 'DroidconAT 2016' property 'sonar.projectVersion', appProject.android.defaultConfig.versionName
property 'sonar.host.url', 'http://localhost:9000' property 'sonar.sources', 'src' property 'sonar.sourceEncoding', 'UTF-8' property 'sonar.java.binaries', 'build'
property 'sonar.exclusions', '**/*Test.java' property 'sonar.core.codeCoveragePlugin', 'jacoco' property 'sonar.jacoco.reportPath', "$appProjectBuildDir/jacoco/testProductionDebugUnitTest.exec" property 'sonar.junit.reportsPath', "$appProjectBuildDir/test-results/productionDebug" }}
Then launch:
./gradlew :app:assembleProductionDebug :app:testProductionDebugUnitTest :app:sonarqube
NODEJS + EXPRESS/* Setup */var fs = require('fs');var express = require('express');var app = express();app.set('port', process.env.PORT || 8080);var port = app.get('port');
/* Speakers list */app.get('/speakers', function(req, res) { res.type('application/json; charset=utf8'); res.status(200).send(fs.readFileSync('data/speakers.json', 'utf8'));});
/* Other web services */// ...
/* Starting the server */app.listen(port, function () { console.log('Express server listening on port ' + port);});
NODEJS + EXPRESSSlow service
sleep(2000);
function sleep(durationMillis) { var now = new Date().getTime(); while (new Date().getTime() < now + durationMillis) { // do nothing }}// Please do not take pictures of this slide,// This is not something I am proud of
EXAMPLE
Then, go to:
https://github.com/Nilhcem/droidconat-2016/tree/master/mockserver
$ npm install
$ npm start
http://localhost:8990/
HOSTS EDITORhttps://play.google.com/store/apps/details?id=com.nilhcem.hostseditor
CHARLES PROXYSimulate a slow connection
Repeat queries
Check the responses
Add some breakpoints to:Cancel an HTTP(s) call
Edit a request
Edit a response
FILL RAMhttps://play.google.com/store/apps/details?id=com.tspoon.androidtoolbelt
ANIMATIONS
Make a screencast (API 19+):
VLC :
$ adb shell screenrecord /sdcard/demo.mp4
$ adb pull /sdcard/demo.mp4
Press the keyboard 'E' key to see
frames one by one
APKTOOL + DEX2JAR + JD-GUI
http://ibotpeaches.github.io/Apktoolhttps://github.com/pxb1988/dex2jar
http://jd.benow.ca
SOME MORE DUMPAPP EXAMPLES$ dumpapp accessToken invalidate$ dumpapp accessToken showfce1235425dcdeadbeef8cafebabe42
$ dumpapp clipboard getHello
$ dumpapp clipboard set "Text to copy"$ dumpapp onTrimMemory$ dumpapp openIntent scheme://open/speaker/3
$ dumpapp gcmTokenuHyMKnEQ:APA91bEHZ6afFLQQMzKgSDjp5y_0397usitPqj_Bp02
$ dumpapp geolocDataLocation[fused 22.5430883,114.1043205 acc=21 et=+21m5s492ms]
$ dumpapp runningServicescom.example.LocationService
STETHO - CUSTOM PLUGINhttp://code.tutsplus.com/tutorials/debugging-android-apps-with-facebooks-stetho--cms-24205
class AppDumperPlugin implements DumperPlugin { @Override public String getName() { return "my_plugin_name"; }
@Override public void dump(DumperContext dumpContext) throws DumpException { PrintStream writer = dumperContext.getStdout(); String commandName = (args.isEmpty()) ? "" : args.remove(0);
if (commandName.equals("test")) { out.println("Hello, World!"); } }}
STETHO - DUMPAPP (EXAMPLE)
(ActivityProvider in a dependency graph in debug)
@Singletonpublic class ActivityProvider implements Application.ActivityLifecycleCallbacks {
private Activity currentActivity;
@Inject public ActivityProvider(Application app) { app.registerActivityLifecycleCallbacks(this); }
public Activity getCurrentActivity() { return currentActivity; }
@Override public void onActivityResumed(Activity activity) { currentActivity = activity; }
@Override public void onActivityPaused(Activity activity) { currentActivity = null; }}
STETHO - DUMPAPP (EXAMPLE)
AppDumperPlugin.java
private void displayCurrentSessionData(PrintStream writer) {
Activity activity = activityProvider.getCurrentActivity();
if (activity instanceof SessionDetailsActivity) {
try {
// Use reflection to access private "session" field
Field field = SessionDetailsActivity.class.getDeclaredField("session");
field.setAccessible(true);
Session session = (Session) field.get(activity);
writer.println(new GsonBuilder().setPrettyPrinting().create().toJson(session));
} catch (Exception e) {
writer.println(e.getMessage());
}
}
}
ADB + SHELL
# Open a deep linking intentadb shell am start -a android.intent.action.VIEW -d "scheme://app/deep/linking"
# List running servicesadb shell dumpsys activity services
# Get the path of an install applicationadb shell pm path app.package.name
# Clear app dataadb shell pm clean app.package.name
# Take a screenshotadb shell screencap -p | perl -pe '\''s/\x0D\x0A/\x0A/g'\'' > screen.png
# Paste text from your computer clipboard to your android devicepbpaste | sed "s/%/%%/g" | sed "s/ /\%\s/g" | xargs adb shell input text
LOCKITOhttps://play.google.com/store/apps/details?id=fr.dvilleneuve.lockito
ACCESSIBILITY SCANNERhttps://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor
https://twitter.com/Nilhcem
https://github.com/Nilhcem/droidconat-2016
http://www.slideshare.net/Nilhcem/the-2016-android-developer-toolbox-vienna
MASTER YOUR TOOLSTO BUILD BETTER APPS