23
Droidcon Moscow 2015 Взаимодействие между потоками в Android Максим Ефимов

Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Embed Size (px)

Citation preview

Page 1: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Droidcon Moscow 2015

Взаимодействие между потоками в Android Максим Ефимов

Page 2: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Кто я такой

0

- Android team lead @ Redmadrobot

- Делал «Мой Билайн», «Открытие», «Альфастрахование»

- Всего выпустил больше 30 Android приложений

- Заморачиваюсь по архитектуре

Page 3: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

- Модель потоков в Android

- Какие сложности таит жизненный цикл

- Чем плохи стандартные решения

- Хорошие решения

О чём будем говорить

1

Page 4: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Модель потоков в Android

2

- Main поток - обрабатывает циклы GUI

- Looper - обеспечивает очередь сообщений внутри потока

- Handler - умеет писать и читать сообщения из очереди Looper’а

- Остальные потоки - по умолчанию не имею цикла, делают «долгие операции»

Page 5: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Примеры долгих операций

3

- Сетевое взаимодействие

- Обращения к базе данных

- Чтение дискового каша

- Преобразование изображений

Page 6: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Жизненный цикл I - Связь с background

4

onCreate onStart onResume onPause

starLoading endLoading

Main thread

Background thread

onClick

Main thread looper

Page 7: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Жизненный цикл II - В идеальном мире

5

onResume onPause

starLoading endLoading

Main thread

Background thread

onClick

Main thread looper

Loop showData

Page 8: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Жизненный цикл III - Повернули экран

6

onResume onDestroy

starLoading endLoading

Main thread - первый Activity Instance

Background thread

onClick

Main thread looper

showData

onResume Loop showData

Main thread - второй Activity Instance

Page 9: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Жизненный цикл IV - Свернули приложение

7

onResume onDestroy

starLoading endLoading

Main thread - первый Activity Instance

Background thread

onClick

Main thread looper

showData

onResume Loop showData

Main thread - второй Activity

Page 10: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Жизненный цикл - сложности

8

- Поток может вернуть результат в уничтоженный объект

- Поток может потерять результат

- Необходимо где-то кешировать результаты

- Нужно, чтобы кеширование было удобным

Page 11: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Решения – Thread

9

Button signInButton = (Button) findViewById(R.id.button_auth); signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { final Activity activity = AuthActivity.this; showProgress(); new Thread(new Runnable() { @Override public void run() { APIFactory.getApi().signIn(); activity.runOnUiThread(new Runnable() { @Override public void run() { goToMainContent(); } }); } }).start(); }});

- Течет память

- Возврат в уничтоженный объект

- Необходимо руками писать в основной поток

Page 12: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Решения – AsyncTask

10

private class AuthTask extends AsyncTask<Void, Void, Boolean> { @Override protected void onPreExecute() { showProgress(); } @Override protected Boolean doInBackground(final Void... params) { try { APIFactory.getApi().signIn(); }catch (Exception e){ return false; } return true; } @Override protected void onPostExecute(final Boolean result) { if(!isCancelled() && result) { goToMainContent(); } }}

Button signInButton = (Button) findViewById(R.id.button_auth);signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { new AuthTask().execute(); }});

- Течет память

- Возврат в уничтоженный объект

Page 13: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Решения – Loader

11

Кода не будет

Пример из документации: 154 строки

Page 14: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Решения – Callback

12

Button signInButton = (Button) findViewById(R.id.button_auth);signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { new AuthRequest(new Callback<Result>(){ @Override public void handleMessage(final Result result) { showData(); } @Override public void handleError(final Exception exception) { showError(exception); } }).run(); }});

- Retrofit

- Volley

- RxJava

На самом деле не решают поставленных проблем

Page 15: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Проблемы решений

13

- Нет привязки к жизненному циклу

- Утечки памяти

- Потеря данных

- Сложная реализация

Page 16: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Хорошие решения – Robospice

14

- Следит за жизненным циклом

- Заточена под сеть

- Есть свой кэш

- Память не течет

- Имеет 100500 плагинов

Page 17: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Хорошие решения – Chronos

15

- Следит за жизненным циклом

- Подхватывает запущенные задачи

- Минималистичен

Page 18: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Chronos - запуск операции

16

class MyActivity extends ChronosActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button startButton = (Button) findViewById(R.id.button_start); startButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { runOperation(new MyOperation()); } }); }}

Page 19: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Chronos - операция

17

class MyOperation extends ChronosOperation<BusinessObject> { @Nullable @Override public BusinessObject run() { final BusinessObject result ; // here you should write what you do to get the BusinessObject return result; } @NonNull @Override public Class<? extends ChronosOperationResult<BusinessObject>> getResultClass(){ return Result.class; } public final static class Result extends ChronosOperationResult<BusinessObject> { }}

Page 20: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Chronos - обработка результата

18

class MyActivity extends ChronosActivity { public void onOperationFinished(final MyOperation.Result result) { if (result.isSuccessful()) { showData(result.getOutput()); } else { showDataLoadError(result.getError()); } } private void showData(BusinessObject data){ //... } private void showDataLoadError(Exception exception){ //... } }

Page 21: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Chronos - трекинг запусков

19

class MyActivity extends ChronosActivity { private Data mData; @Override protected void onResume() { super.onResume(); if (mData == null) { runOperation(new LoadData(), "load_data"); } else { showData(mData); } } public void onOperationFinished(final LoadData.Result result) { if (result.isSuccessful()) { showData(result.getOutput()); } else { showDataLoadError(result.getError()); } }}

Page 22: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

Chronos - что еще?

20

- Отмена операций

- Синхронный запуск

- Bradcast результатов

- Opensource

Page 23: Droidcon Moscow 2015. Взаимодействие между потоками в Android. Максим Ефимов - Redmadrobot

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

21

Вопросы?

[email protected]