Android-монстрик на ім'я FunLib

    Привіт, мене звуть Юра. І я, як і багато з вас, програміст. Як відомо, програмісти — це не просто розробники ПЗ, але творці. Але, на жаль, у повсякденній роботі складно створювати щось нове (особливо, коли ти зайнятий мобільного розробкою). І це часто породжує бажання зібрати свого Франкенштейна (ну або велосипед, якщо вам так хочеться), хоча б у вільний час. Наприклад, мені завжди хотілося зробити свого Франкенштейна, який буде виконувати за мене основну рутинну роботу в 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<Repository> repositories) throws SQLException {
    Dao<User, ?> userDao = getDbHelper().getDao(User.class);
    Dao<Repository, ?> 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<List<Repository>> {
    private String mQuery;

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

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

        List<Repository> 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
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.