Monthly Archives: May 2013

Выложил datepicker для Android

Written by elwood

Ссылка на проект в Bitbucket: https://bitbucket.org/igor_kostromin/android-wheel-datepicker
Контрол был написан для того, чтобы можно было удобно выбирать дату рождения. Выглядит он вот так:

datepicker

Поддерживаются 2 локали: английская (дефолтная, “en-US”) и русская (“ru-RU”). По сути, это был эксперимент на тему того, можно ли по-простому выделять куски xml-layout в отдельные user control’ы по аналогии с тем, как это принято в WPF. Оказалось, что это довольно просто, но к сожалению, нужно вручную создавать классы и разметку, причем эта разметка ничем не отличается от разметки обычных view, и перемешивается в папке layouts. То же самое и с идентификаторами элементов управления, хотя, тут наверное есть способ выносить их в отдельные ids.xml файлы, но опять же – придется всё это делать ручками, и потом при необходимости использовать такой контрол в другом проекте нужно будет копировать файлы из разных директорий и следить за тем, чтобы ничего не потерялось. В общем, можно, но неудобно. Хотелось бы нативной поддержки этого механизма аналогично тому, как это сделано в Windows Presentation Foundation. Напомню, там есть класс UserControl – базовый для всех таких compound control’ов (то есть состоящих из других контролов – в терминологии android-разработки) и его можно описывать в XAML, а потом включать его в другие XAML-файлы, причем идентификаторы дочерних элементов хранятся там же. Как правило, такие контролы помещаются целиком каждый в свою папку, и скопировать их для реюза очень просто.

Из технического – что можно было бы улучшить конкретно в этом элементе управления.
1) Добавить возможность задавать специфические свойства этого контрола в XML (Day, Month, Year, VisibleItems)
2) Убрать некоторые свойства, доставшиеся от базового LinearLayout (например, Orientation, которую мы всегда устанавливаем в Horizontal), чтобы их нельзя было задать как в XML, так и в коде
3) Проверить поведение контрола в более сложных сценариях размещения – когда от него ожидают заполнения всей доступной области по горизонтали / вертикали, или доступный размер меньше необходимого.

PrintAssembly – вывод дизассемблированных java-методов

Written by elwood

Навеяно постом http://elizarov.livejournal.com/29052.html – там описывается, как включить опцию дизассемблирования кода скомпилированных методов. Для этого нужно а) найти плагин hsdis и засунуть его в bin-директорию jdk б) запустить приложение со специальными опциями. От себя ещё добавлю пункт в) добиться того, чтобы метод, код которого хочется получить, был скомпилирован JIT-компилятором, а не просто интерпретирован.

Разбираемся с плагином

В посте лежит ссылка на DLL с hsdis плагином, но только для 32-битных систем. У меня 64-битная Windows 8, поэтому пришлось собирать самому. Делал по инструкции с сайта http://dropzone.nfshost.com/hsdis.htm, всё получилось (правда в первые разы почему-то сборка не прошла до конца по причине отсутствия команды gcc, но я доставил в cygwin пакет с gcc-core и всё собралось). Готовые файлы прилагаю: hsdis-amd64.dll и hsdis-i386.dll

Разбираемся с опциями

Вот такую портянку я использовал

-XX:CompileThreshold=1 -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Program.testMethod -XX:PrintAssemblyOptions=intel -XX:+PrintCompilation -XX:+LogCompilation

-XX:CompileThreshold=1 - чтобы JIT-компилятор компилировал методы после одного вызова
-XX:+UnlockDiagnosticVMOptions - нужная опция, чтобы остальные -XX-опции распознавались
-XX:CompileCommand=print,*Program.testMethod - указываем, что нам нужен дизассемблированный листинг метода testMethod класса Program. Зачем тут звездочка, я не понял, может быть потом разберусь
-XX:PrintAssemblyOptions=intel - устанавливает синтаксис, в котором будет выведен дизассемблированный код. Интеловский синтаксис более удобочитаем, поскольку вокруг регистров отсутствуют проценты %eax%
-XX:+PrintCompilation - выводить список методов, которые скомпилированы в нативный код - для отладки того, что наш искомый метод будет скомпилирован
-XX:+LogCompilation - вывести лог компиляции в файл hotspot.log (по умолчанию)

Разбираемся с компиляцией методов

Наблюдая за тем, как работает тестовая программа, я вывел следующие эмпирические заключения. За их корректность не ручаюсь, но судя по экспериментам, дело обстоит именно так. Методы компилируются после выхода из них и компилируются асинхронно, то есть кладутся в некую очередь для JIT-компилятора, и он потом их компилирует. Таким образом, если вы хотите посмотреть листинг метода main(), то навряд ли это у вас получится, потому что сразу же после выхода из main() программа завершится, и JIT-компилятор не успеет её скомпилировать. Я ставил задержки Thread.sleep(1000) после вызова нужного метода, и рантайм успевал скомпилировать его и вывести листинг в лог. Если же вас интересует именно main, то придётся вынести его тело в другой метод, и вызвать его из основного main, добавив после вызова задержку по времени.