Pull to refresh

Comments 15

Android Query: позволяет манипулировать с UI на порядок проще, мощнее и без потери производительности. Пользуюсь несколько лет. Пример кода (обработчик в адаптере):
       if (view == null) {
            view = layoutInflater.inflate(R.layout.main_adapter_griditem, null);
        }

        final Site site = data.get(position);

        final AQuery aq = listAq.recycle(view);

        if (site.getThumbUrl().equals("")) {
            aq.id(R.id.siteurl).visibility(View.VISIBLE);
            aq.id(R.id.siteurl).text(getHostName.getHost(site.getUrl()));
        }
        else{
            aq.id(R.id.siteurl).visibility(View.GONE);
        }

        if (!TextUtils.equals(site.getShortUser().getAvatar(),"")) {
            aq.id(R.id.userAva).image(site.getShortUser().getAvatar());
        }

        aq.id(R.id.userFullname).text(site.getShortUser().getFullname());
        if (site.getTitle().equals("")) {
            aq.id(R.id.articleTitle).gone();
        }
        else {
            aq.id(R.id.articleTitle).visible().text(site.getTitle());
        }

        int columnHeight = (int) (site.getThumbUrlBigHeight()* (columnWidth/(float)site.getThumbUrlBigWidth()));
        if (columnHeight<=0) {
            columnHeight = columnWidth;
        }
        if (columnHeight>maxHeigth) {
            columnHeight = maxHeigth;
        }
        aq.id(R.id.stgvImageView).height(columnHeight,false);
        aq.id(R.id.stgvImageView).width(columnWidth,false);
        aq.id(R.id.stgvImageView).getImageView().setBackgroundColor(Utils.getStubColor(site.getShortUrl()));

        if (!TextUtils.equals(site.getThumbUrlBig(true),"")) {
            if (aq.shouldDelay(position,view,parent,site.getThumbUrlBig(true))) {
                final Bitmap bitmap = null;
                aq.id(R.id.stgvImageView).image(bitmap);
            }
            else {
                aq.id(R.id.stgvImageView).image(site.getThumbUrlBig(true), true, false, site.getThumbUrlBigWidth(), 0, null, 0,
                        columnHeight / (float)columnWidth);
            }
        }
        aq.id(R.id.articleShare).clickable(true).clicked(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UtilsScreen.onShareClick(activity, site, AdapterMain.this);
            }
        });

(промахнулся, это в ответ recompileme):

Выглядит конечно впечатляюще, хотя и несколько громоздко. Но интересно вот что — aq.id(R.id.button).text("Click Me").clicked(this, "buttonClicked"). Бегло глянув в исходники видно, что здесь чистой воды рефлексия в рантайме (класс Common), так что скорость тут будет не выше чем у Knork, поскольку оба подхода по сути упираются в Method.invoke().
И вот что еще в голову пришло — а Proguard не навредит такому коду? Ну если метод обфусцируется до какого-нибудь «aab» — разве AndroidQuery найдет его по имени buttonClicked?
Ну можно же написать new OnClickListener вместо «buttonclicked» чтобы избежать рефлексии? Но имхо все вот эти парселэбле вс сериалайзебл холливары — на практике сводятся к тому что и так и так выполняется менее чем за милисекунду. А зачем писать много букв если не видно разницы? Как оно отработает с прогвардом — не проверял. Насчёт громоздкости, хм, на яву код становится не очень похож, скорее груви с его краткостью. Плюс библиотека не только заменяет инжекты. Есть работа с сетью лучше чем у окнттп и картинки, лучше чем пикассо, утилит вагон ну и по мелочи.
Конечно, смотрел, гуйс просто чудо для инжекции всего-всего. И на AndroidAnnotations смотрел, тоже неплохая штука. Из подобных вещей я наверное только Dragger пропустил (от того же Уортона).

Но все равно для проектов небольшой сложности мне AndroidAnnotations и RoboGuice показались слишком большими. А вот ButterKnife в свое время в душу запал тем что его код можно весь прочесть за вечер и все понять. И размер APK не увеличивает почти. Какое-то ощущение контроля что ли появляется. Knork — очередная ступень эволюции, самая простая пожалуй на сегодня библиотека для инжекта, пусть и решает очень узкие задачи — инжект видов и listener-ов.
Вот, наконец-то внятно могу сформулировать. Knork занимает как раз пустующую нишу:

1. Мощные аннотации при компиляции (сложно, быстро+нерасширяемо) — AndroidAnnotations, Dagger
2. Мощные аннотации в рантайме (сложно, медленно+расширяемо) — RoboGuice
3. Простые аннотации при компиляции (просто, быстро+нерасширяемо) — ButterKnife
4. Простые аннотации в рантайме (просто, медленно+расширяемо) — Knork
А что понимаете под «сложно/просто»? Остальные параметры понятны, очень классно пояснили.
Сложно/просто — я бы сказал зависит от фич библиотеки (за которыми разумеется стоит объем кода/количество багов).

Ну, скажем, в Knort из фич всего два типа инжекта — инжект View и инжект коллбэка-листенера. Аналогично в ButterKnife. Их все возможности можно понять за пару минут и даже новички поймут все тонкости их работы.

А вот в Roboguice или AndroidAnnotations функционал побольше, документации горы, зато можно инжектить сервисы, произвольные синглтоны, Drawable и другие ресурсы, базы данных… Ну и как следствие — Roboguice утяжелит APK на больше чем 100кб, а Knork — только на 8кб. А это косвенно влияет на скорость запуска и все такое.
Вотжежблин, здравствуйте! Совершенно забыл про существование DroidParts! Крутяцкая либа, за которую вам отдельное спасибо. Но вот только у меня она в одном ряду с RoboGuice, потому как делает сразу все и для всех. А мне хотелось чего-то простого-простого без полноценного DI или там HTTP или там ORM. Просто решить проблему вьюх и не добавлять еще 100к в приложение.
Я не понимаю зачем вы создали еще один велосипед, только если для изучения.
Для инжекта вьюшек использую ButterKnife, для DI Dagger. Доволен и никаких проблем.
На мобильных устройствах нет места аннотациям в рантайме.
Лично у меня проблемы было две: reset() не отменял листенеры, а у меня было самодельное нечто наподобие адаптера, где вью переиспользовались. Так вот инжект+резет+новый инжект приводил к глюкам, потому как onClickListener например заменялся новым, а onBeforeTextChanged — добавлялся еще один. Пришлось переписаь без ButterKnife. Вторая проблема — мне был нужен onKey чтобы обрабатывать DEL в одном EditText, и увы здесь тоже приходится регистрировать листенер вручную (ну или править исходники ButterKnife). Так что это не совсем даже велосипед в классическом понимании, а замена ограничений от compile-time annotation processing на ограничения от runtime annotation processing.

И я не был бы так категоричен по поводоу «нет места» — вон RoboGuice же люди используют, Gson тоже, Otto, ORMLite, да и те же DroidParts многоуважаемого Алекса Янченко комментарием выше!

Последнее, по поводу Butterknife и обработки аннотаций при компиляции. Цитата Уортона в ответа на «почему ButterKnife не работает хотя все правильно написано?»

I think this is just a fundamental flaw in annotation processing-based code generation. Changing a class should cause the processor to run again for it but changing the hierarchy is too-complex a task for an incremental generation. Hopefully this doesn't happen too much. It's just something we are going to have to deal with.


Так что просто поменял все эти проблемы на лишние пару миллисекунд при запуске приложения.
1) Не знаю какая у вас задача, но мне еще ни разу не приходилось использовать reset().
2) Я обычно сам пишу обработчики, поэтому этому опять таки проблем с reset() у меня нет.

3) При разработке Robird я использовал RoboGuice, но это сильно влияло на холодный старт приложения, после появления Dagger я просто перешел на него и понял на сколько он быстрее. На сколько я помню Otto использует механизм генерации кода.

Прежде чем использовать библиотеку с аннотациями в рантайме лучше поискать альтернативу, которая использует генерацию кода.
Конечно же могут возникнуть проблемы с генерацией кода и инкрементальной сборкой проекта, но они решаются простым Clean and Build.
Otto в рантайме аннотации проверяет, код не генерирует.
Sign up to leave a comment.

Articles