Слезаем с велосипедов: опыт использования open source в...

79

description

Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Transcript of Слезаем с велосипедов: опыт использования open source в...

Page 1: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин
Page 2: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Слезаем с велосипедов: Опыт использования open source в Android

Дмитрий Кунин, старший разработчик Яндекс.Музыки для Android

Page 3: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 22

Page 4: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Views management

Boilerplate Top 4

Page 5: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 4: Views management

5

Button happyButton = (Button)findViewById(R.id.the_button); happyButton.setText("Not ok"); happyButton.setOnClickListener( new View.OnClickListener() {

@Override public void onClick(View view) { handleUserNotOk(); } });

Page 6: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 4: Views management

6

Button happyButton = (Button)findViewById(R.id.the_button); happyButton.setText("Not ok"); happyButton.setOnClickListener( new View.OnClickListener() {

@Override public void onClick(View view) { handleUserNotOk(); } }); // из 8 строк полезных только 2, а это 25%

Page 7: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Views management: Butterknife

Boilerplate Top 4

Page 8: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Butterknife

• Декларативная замена findViewById

• Декларативное задание OnClickListener

• Мульти-сеттеры

• можно подружить с proguard

• и все это compile time

• использовать и интегрировать очень просто

Butterknife: http://jakewharton.github.io/butterknife/ 8

Page 9: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативная замена findViewById

9

@InjectView(R.id.title) TextView title; !

… !

ButterKnife.inject(this); title.setText("Либа моей мечты");

Page 10: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное задание OnClickListener

10

!

@OnClick(R.id.submit) public void submit() { server.sendForm(); }

!

@OnClick(R.id.sayhi) public void sayHi(Button button) { button.setText("Hello!"); }

Page 11: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

можно подружить с proguard

11

# Butterknife -dontwarn butterknife.internal.** -keep class butterknife.** { *; } -keep class **$$ViewInjector { *; } !

-keepclasseswithmembernames class * { @butterknife.InjectView <fields>; } -keepclasseswithmembernames class * { @butterknife.OnClick <methods>; } https://github.com/JakeWharton/butterknife/pull/117

Page 12: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

и все это compile time

12

public void inject(ExampleActivity activity) { activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578); activity.footer = (android.widget.TextView) activity.findViewById(2130968579); activity.title = (android.widget.TextView) activity.findViewById(2130968577); }

Page 13: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

https://github.com/JakeWharton/kotterknife

Kotterknife

Page 14: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Butterknife

http://jakewharton.github.io/butterknife/

14

compile 'com.jakewharton:butterknife:6.0.0'

Page 15: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Database management

Boilerplate top 3

Page 16: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Очень простая модель

*Здесь и далее модификаторы доступа, акцессоры и мутаторы не указаны простоты ради. То же самое относится к проверкам на null.

16

class Photo { long id; String name; long lat; long lon; String pathToFile; }

Page 17: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.1: SqliteOpenHelper

17

public void onCreate(SQLiteDatabase db) { db.execSQL("create table photos ( id integer primary key autoincrement, name text, lat integer, lon integer, pathToFile text);"); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// crazy update stuff }

Page 18: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.1: SqliteOpenHelper

18

public void onCreate(SQLiteDatabase db) { db.execSQL("create table photos ( id integer primary key autoincrement, name text, lat integer, lon integer, pathToFile text);"); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// crazy update stuff }

Page 19: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.2: Query

19

public Cursor getPhotoById(long id) { return database.query ( "photos", // table, null, // columns, "id =?", // selection, new String[] { String.valueOf(id) } // selectionArgs, null, // groupBy null, // having null, // orderBy); }

Page 20: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.3: Conversion

20

public Photo cursorToPhoto(Cursor cursor) { Photo photo = new Photo(); photo.id = cursor.getLong(0); photo.name = cursor.getString(1); photo.lat = cursor.getLong(2); photo.lon = cursor.getLong(3); photo.path = cursor.getString(4); return photo; }

Page 21: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.3: Conversion

21

public Photo cursorToPhoto(Cursor cursor) { Photo photo = new Photo(); photo.id = cursor.getLong(0); photo.name = cursor.getString(1); photo.lat = cursor.getLong(2); photo.lon = cursor.getLong(3); photo.path = cursor.getString(4); return photo; } // что если поменяется порядок столбцов?

Page 22: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.3: Conversion

22

public Photo cursorToPhoto(Cursor cursor) { Photo photo = new Photo(); photo.id = cursor.getLong(0); photo.name = cursor.getString(1); photo.lat = cursor.getLong(2); photo.lon = cursor.getLong(3); photo.path = cursor.getString(4); return photo; } // что если поменяется порядок столбцов? // где-то еще нужно менеджить курсор

Page 23: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Boilerplate Top 3.3: Conversion

23

public Photo cursorToPhoto(Cursor cursor) { Photo photo = new Photo(); photo.id = cursor.getLong(0); photo.name = cursor.getString(1); photo.lat = cursor.getLong(2); photo.lon = cursor.getLong(3); photo.path = cursor.getString(4); return photo; } // что если поменяется порядок столбцов? // где-то еще нужно менеджить курсор // не забывайте править каждый раз при смене модели

Page 24: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Database management: Cupboard

Boilerplate top 3

Page 25: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Cupboard

• Нет необходимости в наследовании от классов библиотеки

• Создавалась специально для Android

• Не менеджит отношения между объектами

• Автоматически генерирует и обновляет таблицы

• Прозрачные трансформации POJO -> ContentValues, Cursor -> POJO

Cupboard: https://bitbucket.org/qbusict/cupboard 25

Page 26: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Нет необходимости в наследовании от классов библиотеки

26

class Photo { Long _id; String name; long lat; long lon; String pathToFile; }

Page 27: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Автоматически генерирует и обновляет таблицы

27

static { cupboard().register(Photo.class); } !

@Override public void onCreate(SQLiteDatabase db) { cupboard().withDatabase(db).createTables(); } !

@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

cupboard().withDatabase(db).upgradeTables(); }

Page 28: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Трансформации POJO -> ContentValues, Cursor -> POJO

28

!

Photo photo = … cupboard.withDatabase(db).put(photo);

!

!

long photoId = … photo = cupboard.withDatabase(db).get(Photo.class, photoId);

Page 29: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Делать нужные выборки очень просто

29

List<Photo> kittyPhotos = cupboard().withDatabase(db) .query(Photo.class) .withSelection("name like %?%", "kitty") .list();

Page 30: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Кастомные конверсии

30

public interface FieldConverter<T> { T fromCursorValue(Cursor cursor, int columnIndex); !

void toContentValue(T value, String key, ContentValues values); !

ColumnType getColumnType(); !

}

Page 31: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Cupboard

https://bitbucket.org/qbusict/cupboard

31

compile 'nl.qbusict:cupboard:2.0.1'

Page 32: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Image loading

Boilerplate Top 2

Page 33: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Чего мы хотим?

• асинхронности

• кеширование в память

• трансформации (crop, scale, round, desaturate etc.)

• анимации

• bitmap pooling

• placeholder image

• кеширование на диск

Boilerplate Top 2: Image loading 33

Page 34: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Чего мы хотим?

• асинхронности

• кеширование в память

• трансформации (crop, scale, round, desaturate etc.)

• анимации

• bitmap pooling

• placeholder image

• кеширование на диск

Boilerplate Top 2: Image loading 34

Page 35: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Чего мы хотим?

• асинхронности

• кеширование в память

• трансформации (crop, scale, round, desaturate etc.)

• анимации

• bitmap pooling

• placeholder image

• кеширование на диск

Boilerplate Top 2: Image loading 34

Page 36: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Что такое Bitmap Pooling?// вот так далвик справляется с выделением памяти для битмапов

GC_FOR_ALLOC freed 1105K, 14% free 10933K/12615K, paused 33ms, total 34ms

GC_FOR_ALLOC freed 337K, 13% free 11055K/12615K, paused 25ms, total 26ms

GC_FOR_ALLOC freed 278K, 14% free 10951K/12615K, paused 24ms, total 24ms

GC_CONCURRENT freed 633K, 11% free 11317K/12615K, paused 16ms+3ms, total 79ms

WAIT_FOR_CONCURRENT_GC blocked 16ms

WAIT_FOR_CONCURRENT_GC blocked 15ms

Boilerplate Top 2: Image loading 35

Page 37: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Что такое Bitmap Pooling?// вот так далвик справляется с выделением памяти для битмапов

GC_FOR_ALLOC freed 1105K, 14% free 10933K/12615K, paused 33ms, total 34ms

GC_FOR_ALLOC freed 337K, 13% free 11055K/12615K, paused 25ms, total 26ms

GC_FOR_ALLOC freed 278K, 14% free 10951K/12615K, paused 24ms, total 24ms

GC_CONCURRENT freed 633K, 11% free 11317K/12615K, paused 16ms+3ms, total 79ms

WAIT_FOR_CONCURRENT_GC blocked 16ms

WAIT_FOR_CONCURRENT_GC blocked 15ms

Boilerplate Top 2: Image loading 36

на один фрейм у нас 1000/60 = 16мсек

Page 38: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Image loading: Glide

Boilerplate top 2

Page 39: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Glide

• Простой интерфейс

• Работает асинхронно

• А может работать синхронно

• Кеширует в память

• Кеширует на диск

• Анимации

• Трансформации

Glide: https://github.com/bumptech/glide 38

Page 40: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Простой интерфейс

39

Glide.with(applicationContext) .load(imageUrl) .crossfade() .into(imageView);

Page 41: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Поддерживает блокирующую загрузку

40

Bitmap bmp = Glide.with(applicationContext) .load(yourUrl) .asBitmap() .centerCrop() .into(500, 500) .get() // блокирует поток до завершения загрузки

Page 42: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Кеширование

41

public class AwesomeApp extends Application { @Override public void onCreate() { Glide.setup(new GlideBuilder(this) .setDiskCache(…) // LRU, 250MB .setMemoryCache(…) // LRU, 40% RAM ); } }

Page 43: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Кастомизация цели загрузки

42

public interface Target<R> extends LifecycleListener { !

public void onLoadStarted(Drawable placeholder); public void onLoadFailed(Exception e, Drawable errorDrawable); public void onResourceReady(R resource, GlideAnimation<? super R> glideAnimation); public void onLoadCleared(Drawable placeholder); public void getSize(SizeReadyCallback cb); public void setRequest(Request request); public Request getRequest(); !

}

Page 44: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

43

public interface BitmapPool { public void setSizeMultiplier(float sizeMultiplier); !

public boolean put(Bitmap bitmap); !

public Bitmap get(int width, int height, Bitmap.Config config); !

public Bitmap getDirty(int width, int height, Bitmap.Config config); public void clearMemory(); !

public void trimMemory(int level); } // НЕ панацея!

Page 45: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Glide

https://github.com/bumptech/glide

44

compile 'com.github.bumptech.glide:glide:3.3.1'

//optional

compile 'com.github.bumptech.glide:okhttp-integration:1.0.+'

compile 'com.squareup.okhttp:okhttp:2.0.+'

Page 46: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Взаимодействие с сервером

Boilerplate Top 1

Page 47: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Чего мы хотим?

• манипулировать параметрами запроса

• удобно обрабатывать ошибки

• ставить нужные заголовки

• как можно меньше думать о http

• незаметно парсить ответы

• а главное, чтобы все было асинхронно

Boilerplate Top 1: Client-Server Interaction 46

Page 48: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Взаимодействие с сервером: Retrofit

Boilerplate top 1

Page 49: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Retrofit

• Декларативное описание серверного (REST?) API

• Гибкое задание параметров запроса

• Автоматические конверсии параметров запросов/ответов

• Манипуляция заголовками

• Синхронно/Асинхронно/Реактивно

Retrofit: http://square.github.io/retrofit/ 48

Page 50: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное описание серверного API

49

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy); !

@Multipart @POST("/{user}/photos/add") Photo addPhoto(@Path("user") String user, @Body Photo photo, @Part TypeFile imageFile); }

Page 51: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное описание серверного API

50

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy); !

@Multipart @POST("/{user}/photos/add") Photo addPhoto(@Path("user") String user, @Body Photo photo, @Part TypeFile imageFile); }

Page 52: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное описание серверного API

51

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy); !

@Multipart @POST("/{user}/photos/add") Photo addPhoto(@Path("user") String user, @Body Photo photo, @Part TypeFile imageFile); }

Page 53: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное описание серверного API

52

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy); !

@Multipart @POST("/{user}/photos/add") Photo addPhoto(@Path("user") String user, @Body Photo photo, @Part TypeFile imageFile); }

Page 54: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Декларативное описание серверного API

53

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy); !

@Multipart @POST("/{user}/photos/add") Photo addPhoto(@Path("user") String user, @Body Photo photo, @Part TypeFile imageFile); }

Page 55: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Использование

54

RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("https://api.example.com") .build(); !

PhotoService photoService = restAdapter.create(PhotoService.class); !

// теперь можно использовать сервис List<Photos> photos = photoService.photos("popular");

Page 56: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Гибкое задание параметров запроса

55

PhotoService photoService = … !

// /photos/list List<Photos> photos = photoService.photos(null); !

… !

// /photos/list?sort="rating" List<Photos> bestPhotos = photoService.photos("rating");

Page 57: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Конвертация параметров запросов/ответов

56

!

// По-умолчанию объект типа Photo будет сериализован в // JSON при помощи GSON при запросе и десериализован из ответа !

Photo photo = photoService.addPhoto(userId, newPhoto, imageFile);

Page 58: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Конвертация параметров запросов/ответов

57

// Конверторы задают преобразования TypedValue -> Object и обратно. public interface Converter { !

Object fromBody(TypedInput body, Type type); TypedOutput toBody(Object object); }

Page 59: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Конвертация параметров запросов/ответов: Retrofit Converters

https://github.com/square/retrofit/tree/master/retrofit-converters

Доступные конверторы:

• Jackson

• Protobuf

• SimpleXml

• Wire

58

Page 60: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Манипуляция заголовками (статические)

59

@Headers( { "Accept: application/json", "User-Agent: Agent-007" }; @GET("/photos/list") List<Photo> photos();

Page 61: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Манипуляция заголовками (динамические)

60

@Headers( { "Accept: application/json", "User-Agent: Agent-007" }; @GET("/photos/list") List<Photo> photos(); !

@GET("/photos/{user}/list") List<Photo> photos(@Header("Authorization") String authorization, @Path("user") String user); !

Page 62: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Перехват запросов

61

RequestInterceptor requestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { request.addHeader("Authorization", UserData.getAuthToken()); } };

Page 63: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Перехват запросов

62

RequestInterceptor requestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { request.addHeader("Authorization", UserData.getAuthToken()); } }; // Будет перехватывать ВСЕ запросы RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("…") .setRequestInterceptor(requestInterceptor) .build();

Page 64: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Синхронно

63

public interface PhotosService { !

@GET("/photos/list") List<Photos> photos(@Query("sort") String sortBy);

}

Page 65: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно

64

public interface PhotosService { !

@GET("/photos/list") void photos(@Query("sort") String sortBy, Callback<List<Photo>> callback); }

!

}

Page 66: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно

65

public interface PhotosService { !

@GET("/photos/list") void photos(@Query("sort") String sortBy, Callback<List<Photo>> callback); }

} !

public interface Callback<T> { void success(T t, Response response); void failure(RetrofitError error); }

Page 67: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно в паре с Robospice

66

// https://github.com/stephanenicolas/robospice/wiki/Retrofit-module !

public abstract class SpiceRequest<RESULT> implements Comparable<SpiceRequest<RESULT>> {

public abstract RESULT loadDataFromNetwork() throws Exception; } !

public interface RequestListener<RESULT> { void onRequestFailure(SpiceException spiceException); void onRequestSuccess(RESULT result); } spiceManager.execute(request, listener);

Page 68: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно в паре с Robospice

67

// https://github.com/stephanenicolas/robospice/wiki/Retrofit-module !

public abstract class SpiceRequest<RESULT> implements Comparable<SpiceRequest<RESULT>> {

public abstract RESULT loadDataFromNetwork() throws Exception; } !

public interface RequestListener<RESULT> { void onRequestFailure(SpiceException spiceException); void onRequestSuccess(RESULT result); } spiceManager.execute(request, listener);

Page 69: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно в паре с Robospice

68

// https://github.com/stephanenicolas/robospice/wiki/Retrofit-module !

public abstract class SpiceRequest<RESULT> implements Comparable<SpiceRequest<RESULT>> {

public abstract RESULT loadDataFromNetwork() throws Exception; } !

public interface RequestListener<RESULT> { void onRequestFailure(SpiceException spiceException); void onRequestSuccess(RESULT result); } spiceManager.execute(request, listener);

Page 70: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Асинхронно в паре с Robospice

69

// https://github.com/stephanenicolas/robospice/wiki/Retrofit-module !

public abstract class SpiceRequest<RESULT> implements Comparable<SpiceRequest<RESULT>> {

public abstract RESULT loadDataFromNetwork() throws Exception; } !

public interface RequestListener<RESULT> { void onRequestFailure(SpiceException spiceException); void onRequestSuccess(RESULT result); } spiceManager.execute(request, listener);

Page 71: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Реактивно

70

public interface PhotosService { !

@GET("/photos/list") Observable<List<Photos>> photos(@Query("sort") String sortBy); !

}

Page 72: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Реактивно

71

photoService.photos("popular") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Photo>>() {

@Override public void call(List<Photo> list) { // обработка результата запроса } });

Page 73: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Реактивно

72

photoService.photos("popular") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Photo>>() {

@Override public void call(List<Photo> list) { // обработка результата запроса }

});

Page 74: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Реактивно

73

photoService.photos("popular") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<List<Photo>>() {

@Override public void call(List<Photo> list) { // обработка результата запроса } });

Page 75: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

74

photoService.photos("popular") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<Photo>>() { public void onCompleted() { … } public void onError(Throwable e) { … } !

public void onNext(List<Photo> list) { … } !

});

Page 76: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Retrofit

http://square.github.io/retrofit/

75

compile 'com.squareup.retrofit:retrofit:1.7.0'

compile 'com.squareup.okhttp:okhttp:2.0.0'

compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'

// optional

compile 'com.netflix.rxjava:rxjava-android:0.20.5'

Page 77: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Демо-проект

https://github.com/d-kunin/yac2014/ 76

Page 78: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

Полезные ссылки:

• Демо: https://github.com/d-kunin/yac2014

• http://gradleplease.appspot.com/

• http://androidweekly.net/

• https://github.com/JakeWharton/u2020

Спасибо за внимание!

Page 79: Слезаем с велосипедов: опыт использования open source в Android. Дмитрий Кунин

_platon

https://www.facebook.com/dev.kunin 78

Дмитрий Кунин

старший разработчик Яндекс.Музыки для Android

Контакты

[email protected]