Slide 1

Slide 1 text

Developing an Android library DINO KOVAČ

Slide 2

Slide 2 text

01 WHY?

Slide 3

Slide 3 text

WHY A LIBRARY? • DRY - don’t repeat yourself • easier than copy/pasting classes

Slide 4

Slide 4 text

WHY AN OPEN SOURCE LIBRARY? • saving others time • useful contributions from community • eternal fame!

Slide 5

Slide 5 text

02 WHAT?

Slide 6

Slide 6 text

DOES IT MAKES SENSE TO BUILD IT? • is there a real need? • any existing libraries?

Slide 7

Slide 7 text

PICK A GOOD NAME • one that doesn’t already exist • should make sense • bonus points if it’s amusing • example: • HTTParty - Makes http fun again!

Slide 8

Slide 8 text

03 HOW?

Slide 9

Slide 9 text

MIND THE API • primary way users interact with your lib • make it easy to use • make it robust (avoid footguns!)

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

HTTPURLCONNECTION HttpURLConnection urlConnection = null;
 try {
 URL url = new URL("https://api.github.com/markdown/raw");
 connection = (HttpURLConnection) url.openConnection();
 connection.setDoOutput(true);
 connection.setChunkedStreamingMode(0);
 
 OutputStream out = new BufferedOutputStream(connection.getOutputStream());
 writeStream(out);
 
 InputStream in = new BufferedInputStream(connection.getInputStream());
 readStream(in);
 } catch (IOException e) {
 // handle this
 } finally {
 if (connection != null) {
 connection.disconnect();
 }
 }

Slide 12

Slide 12 text

HTTPURLCONNECTION

Slide 13

Slide 13 text

OKHTTP Request request = new Request.Builder()
 .url("https://api.github.com/markdown/raw")
 .post(RequestBody.create(MediaType.parse("text/plain"), "post body"))
 .build();
 
 try {
 Response response = client.newCall(request).execute();
 } catch (IOException e) {
 // handle this
 }

Slide 14

Slide 14 text

FAIL FAST • as much validation as reasonably possible • fail as fast as possible

Slide 15

Slide 15 text

FAIL FAST public Builder post(RequestBody body) {
 return method("POST", body);
 }
 
 public Builder method(String method, RequestBody body) {
 if (method == null || method.length() == 0) {
 throw new IllegalArgumentException("method == null || method.length() == 0");
 }
 if (body != null && !HttpMethod.permitsRequestBody(method)) {
 throw new IllegalArgumentException("method " + method + " must not have a request body.");
 }
 if (body == null && HttpMethod.requiresRequestBody(method)) {
 throw new IllegalArgumentException("method " + method + " must have a request body.");
 }
 this.method = method;
 this.body = body;
 return this;
 }

Slide 16

Slide 16 text

DON’T EXPOSE THE INTERNALS • package-protected classes • private or protected methods

Slide 17

Slide 17 text

APP RESOURCES LIBRARY RESOURCES MERGED RESOURCES

Slide 18

Slide 18 text

APP RESOURCES LIBRARY RESOURCES MERGED RESOURCES @string/app_name @string/app_name @string/app_name

Slide 19

Slide 19 text

APP RESOURCES LIBRARY RESOURCES MERGED RESOURCES @string/app_name (en) @string/app_name (fr) @string/app_name (de) @string/app_name (en) @string/app_name (fr) @string/app_name (de) @string/app_name

Slide 20

Slide 20 text

ANDROID SPECIFICS • build.gradle • resourcePrefix 'dbinspector_'

Slide 21

Slide 21 text

WRITE THE DOCS • what does it do? • how do I use it? • maybe an example app?

Slide 22

Slide 22 text

DISTRIBUTE • don’t use maven central, use jcenter • automate deployment

Slide 23

Slide 23 text

SHAMELESS SELF-PROMOTION • https://github.com/infinum/android_dbinspector • https://github.com/reisub/HttPizza

Slide 24

Slide 24 text

Any questions? [email protected] @DINO_BLACKSMITH Visit infinum.co or find us on social networks: infinum.co infinumco infinumco infinum