the 2016 android developer toolbox [vienna]

77
#droidconvie THE 2016 ANDROID DEVELOPER TOOLBOX

Upload: nilhcem

Post on 15-Apr-2017

141 views

Category:

Internet


3 download

TRANSCRIPT

#droidconvie

THE 2016 ANDROIDDEVELOPER TOOLBOX

#droidconvie

"Use the right tools for the right job"

(with the Android Plugin for Gradle)

BUILD VARIANTS

U+2020https://github.com/JakeWharton/u2020

DEBUG SCREENExample from Google iosched

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

MEASURING TOOLS

ANDROID STUDIO(Android Monitor tab)

DETECT MEMORY LEAKS

LEAK CANARYhttps://github.com/square/leakcanary

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);

}

}

CODE STATIC ANALYSIS TOOLS

Lint

Error Prone (Google)

Infer (Facebook)

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

TESTING TOOLS

MOCK SERVER

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

HTTP DEBUGGING

HTTP DEBUGGING

mitmproxy

Fiddler

Charles proxy

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

EDIT A RESPONSE

ANDROID STATERESTORING

DON'T KEEP ACTIVITIES

FILL RAMhttps://play.google.com/store/apps/details?id=com.tspoon.androidtoolbelt

ANDROID DEVICE MONITOR - STOP PROCESS

ANALYZING TOOLS

DEVELOPER OPTIONS

UIAUTOMATORVIEWER

ANIMATIONSDeveloper options -> Animation scale

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

JADXhttps://github.com/skylot/jadx

ANDROID STUDIO 2.2(Build > Analyze APK)

STETHO

STETHO - UI

STETHO - NETWORK

STETHO - RESOURCES

STETHODUMPAPP

STETHO - DUMPAPP

STETHO - DUMPAPP

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 - CUSTOM PLUGIN

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());

}

}

}

STETHO CONSOLE + RHINO

$#*!,I FORGOT THESE TOOLS!

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

POSTMANhttps://www.getpostman.com/

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

VYSORhttp://www.vysor.io

AS A CONCLUSION...

CHOOSE ACCORDINGTO YOUR NEEDS AND

TASTES

THE 2016 ANDROIDDEVELOPER TOOLBOX

(EXAMPLE OF AN)ANDROID DEVELOPER

TOOLBOX

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