Android-монстрик по имени FunLib

ffa54e0b8d3c6bf535da84516987b7af.pngПривет, меня зовут Юра. И я, как и многие из вас, программист. Как известно, программисты — это не просто разработчики ПО, но создатели. Но, к сожалению, в повседневной работе сложно создавать что-то новое (особенно, когда ты занят мобильной разработкой). И это часто порождает желание собрать своего Франкенштейна (ну или велосипед, если вам так хочется), хотя бы в свободное время. Например, мне всегда хотелось сделать своего Франкенштейна, который будет выполнять за меня основную рутинную работу в Android-приложении.И вот у меня недавно, наконец, нашлось свободное время на это дело (прим. автора: здесь можно просто за меня порадоваться)! Почитав разные статьи о том, что сейчас модно, или стало модным ещё много лет назад, я собрал для себя примерный список того, из чего будет состоять мой друг. И вот чему он у меня пока научился:

Ходить! Он ходит в интернеты, достаёт оттуда данные, и приносит к себе Помнить! Если надо, он запомнит то, что взял в интернетах, может даже сперва обработать эти данные И вообще — выполнять несколько задач одновременно! Причём, не надо заморачиваться над тем, что вдруг наш монстрик решит, например, покувыркаться Сколько разных элементов мне пришлось свалить в одну кучу, чтоб мой монстрик, по имени FunLib ожил! Тут собрались такие звёзды, как retrofit, eventbus, jobqueue… Но давайте по-порядку! Итак, кто за что отвечает в моём детище:

Хождение в интернетВ интернет мы ходим, используя Retrofit+OkHttp. Это позволяет делать всю работу быстро, аккуратно и при поддержке большого комьюнити. Согласитесь, очень удобно делать запрос на сервис примерно таким способом: public interface GithubApi { @GET (»/search/repositories? sort=stars&order=desc») SearchResult search (@Query («q») String query); } И ведь как круто получается, прям по-евангелистки! Ведь разработка реально ведётся не на уровне реализации, а, буквально, на уровне интерфейса! Вообще, очень много чего можно добавить в запрос, по разному настроить его. Но т.к. это не сама суть статьи, оставлю это на ваше самостоятельное изучение. Ну или было бы здорово, если бы кто-нибудь написал, как он круто использует эти библиотеки, особенно, если его ходы не тривиальны и не освещены в офф. гайде.

Память в БД За память у него отвечает ORMLite. Как говорится, на вкус и цвет все фломастеры разные. Мне это решение нравится больше всего. Особенно, к плюсам этой библиотеки я отношу вот что: Из базы можно получать уже готовые объекты, а не сырой набор данных (даже с данными по вторичным ключам) Можно получать крусор, выполняя ORM запрос Можно получать курсор, выполняя обычный sql-запрос, со всеми вытекающими возможностями Такое решение наверняка будет легко понятно каждому, кто будет в будущем сопровождать/читать ваш код Здесь, как обычно — аннотируем нужные классы и поля как @DatabaseTable и @DatabaseField, соответственно. После чего спокойно можем сложить, или, если надо, достать, данные в БД: private void saveRepositories (List repositories) throws SQLException { Dao userDao = getDbHelper ().getDao (User.class); Dao repositoryDao = getDbHelper ().getDao (Repository.class);

for (Repository repository: repositories) { userDao.createOrUpdate (repository.getOwner ()); repositoryDao.createOrUpdate (repository); } } PS: к сожалению, пока FunLib не умеет удобно нотифаить лоадеры по URI… Да и его активити с фрагментами не предоставляют функционало для удобной работы с лоадерами, но всё в ваших руках! Пулл-рекввесты ждут вас. Ну или ждите, пока я это сделаю : P

Мозги для параллельной работы Для этого немаловажного процесса был выбран инструмент под названием Priority Job Queue. Почему же мы не сделали свой собственный сервис? Да всё просто — мне было интересно использовать эту библиотеку =) Да и манифест остаётся чист. И, что не мало важно, это решение довольноприемлемо аккуратно вписывается в нашу Центральную Нервную Систему (чуть ниже про неё сказано). Но мы с FunLib сели, подумали, и решили, что тот Job, от которого команда Path предлагает нам наследоваться, слишком монструозен. Мне будет тяжело давать моему малышу какие-нибудь команды. Ну или ему будет не так просто их понять. Поэтому был сделан карапуз по имени FunJob, который умеет просто выполнить нужную нам работу в методе public abstract T doJob () throws Throwable.Пример работы. Внимание! Монстр опасен! Заглядывать только отчаявшимся смельчакам! public class SearchJob extends FunJob> { private String mQuery;

public SearchJob (int id, String query) { super (id); mQuery = query; }

@Override public List doJob () throws Throwable { SearchResult searchResult = ((GithubApi) getApi ()).search (mQuery);

List repositories = searchResult.getRepositories ();

return repositories; } } Центральная Нервная Система или просто DI Для такой важной задачи, как доставка БД, интернета, и прочей информации в мозг и обратно к телу роботика, был использован компонент по имени Dagger, реализующий Dependency Injector. Благо, наши мозги умеют делать инъекцию в Job тогда, когда Job уже готов выполняться! Поэтому FunJob, когда делает свою работу, уверенно может обращаться к БД, к API, и вообще знает, что он — это он! Ведь это так важно связать мозги с телом! А для отправки команды от мозгов к телу была использована штука под названием EvenBus. Изначально хотел использовать Otto, но, по непонятным причинам FunLib его невзлюбил, и я быстро отказался от него. Ну ничего — EventBus тоже отлично справляется со своей задачей! Тело всегда вовремя получает нужные команды!

Ready Steady Go! На этом пока я решил сделать привал, завершить свой рассказ и получить от вас фитбэк. И уже после этого я продолжу дальше развивать моего кроху.В примере вы можете отчётливо увидеть, как управлять работой FunLib — всего-то нужно:

наследоваться от FunApp, прописать в нём путь до API, интерфейс, работающий с API и ваш класс DbHelper наследоваться от FunActivity/FunFragment, а там уже удобно стартовать работу, получать доступ к API и БД сделать то, что вам нужно! ;) Постскриптум Возможно, прочитав про лоадеры, вы подумаете, что я, наконец, решу прикрутить к приложению ContentProvider. Но нет, этого делать я не планирую, т.к. думаю не спроста в офф. гайде написано: You don’t need to develop your own provider if you don’t intend to share your data with other applications. В моей практике ещё не приходилось делать такого приложения, которые бы предоставляло данные другим приложениям. И не надо из-за этого кидать в меня помидорами! Всем нам разные задачи попадаются.Так же пока печалит то, что нужно самостоятельно следить за тем, какой ID для FunJob был выставлен. Но ничего — это будет исправлено, и это станет очередной вкусняшкой!

Кто пропустил ссылку на репозиторий, ловите: https://github.com/senneco/FunLib

Встретимся в комментах и в пулл-реквестах : D

© Habrahabr.ru