Все, что описывается в постах серии “Мобильная археология” подразумевает, что ответ на вопросы вроде “А почему не вот так?” всегда ровно один - не было готового, было нельзя, забудь про любые библиотеки, их не было.
Заказы
В свое время Blackberry был гаджетом серьезных парней с не менее серьезными деньгами - достаточно сказать, что это они одними из первых начали пиариться в кино. Если ты бизнесмен, у тебя Blackberry.

У него идеальная клавиатура. Он хорошо сделан. Это статус, это отличное устройство для работы. Поэтому заказы на приложения под Blackberry перли валом, а Axmor, в котором я тогда работал, умело этим пользовался. По факту из всех, кто тогда занимался разработкой приложений, они умели и знали больше всех, слишком много было крупных проектов.
Разработка
При всем этом разработка под Blackberry была кромешным адом - даже под J2ME работать было как-то приятнее, что ли.
Тулинг
IDE JDE
Примерно вот так выглядела поделка, которая гордо называлась Blackberry JDE (Java Development Environment, не какой-то там IDE):

Это было написанное на Swing приложение, которое выглядело отвратно, работало отвратно и в принципе все, что только могло, делало отвратно. Completion работал через раз и по праздникам. По сути, все что более-менее нормально можно было там делать - это отлаживаться. И это потому, что тогда я еще не мог вырезать оттуда дебаггер и перекинуть его в нормальную IDE. В итоге, код я писал в NetBeans, попробовав это делать в десятке сред того времени. Именно тогда я получил тот самый первый и единственный негативный опыт разработчика, после которого он больше никогда не использует продукт: поставил IntelliJ IDEA, промучался с настройкой проекта день, получил пачку нафиг мне ненужных конфигов в .idea в проектной папке, заколебался понимать, что же черт побери значит facet в их терминологии, и после этого принципиально не использовал продукты JetBrains лет десять. Ну и UI у них тогда был мягко говоря так себе:

Буквально перед смертью Blackberry все-таки сподобилась сделать плагин для Eclipse, который в итоге работал так плохо, что я еще долгое время оставался на своем стеке.
Бинари
В результате компиляции ты получал .cod-файл, который иногда был .cod-файлом (конечный бинарь), а иногда зипом с пачкой .cod-файлов. В итоге чтобы дать клиенту скачать очередную версию приложения надо было:
- Собрать билд
- Раззиповать
- Выложить все файлы куда-нибудь
- В .jad-файле перечислить их все
Где-то по пути случалась подпись всей этой пачки на серверах Blackberry, занимавшая от пары минут до пары дней (сколько именно ты никогда не знал). Но даже сборка самих билдов с выкладкой уже превращалась в немалый геморрой. В Axmor до меня ее обычно делали руками. До сих пор помню разговор с Андреем Жарких (Solo), моим PMом у которого я собственно всему и учился:
- Андрей, задолбало, давай что-то придумаем уже
- Стас, ну емое, там три файла

Я тогда плюнул и через bb-ant-tools сделал простенький скрипт, который генерил все автоматически, заливал файло на FTP и выплевывал HTML для вставки на страничку с билдами. Через пару недель билдов стало три, а файлов девять.
Потом билдов стало пять, в каждом файлов по семь.
Потом все стали использовать мой скрипт, потому что иначе было невозможно.
При этом лучше менеджера, чем Андрей, я не знаю до сих пор. Ну, разве что я сам )
Зоопарк версий устройств
Blackberry был первым, кто изобрел бессмысленный и беспощадный зоопарк разрешений, версий JDK, версий примерно всего что только можно придумать. Все устройства работали вроде бы одинаково, но на самом деле слегка по-разному.
Грубый пример такой (и это реальный пример): есть список звонков, есть обьект типа CallLog. Из него надо выцепить номер телефона и что-нибудь с ним сделать в приложении. В версии 4.3 API возвращало String. В версии 4.5 Object, внутри которого мог быть либо String, либо CallLog. В версии 4.7 по документации должен был возвращаться CallLog, но в реальности приходил String. В версии 5.0 приходил CallLog c пустым номером. Или просто null. Ну а что такого?
И так было со всем. Новое разрещение экрана? Ок, у нас же есть встроенные лайауты, все ок? Нет, не ок. Никто не использовал их встроенные компоненты, ибо задизайнить на них можно было примерно ничего. Отрисовку было невозможно перегрузить целиком у какого-нибудь TextField, его приходилось рисовать с нуля на Graphics‘е. Моим святым граалем была универсальная библиотека GUI, которую я делал проектов шесть или семь. В конце концов я сдался, потому что даже если бы ты хотел написать GUI с нуля, времени писать всю стандартную либу контролов попросту не было.
Другим прекрасным примером зоопарка был максимальный размер файла на файловой системе. Делали мы как-то диктофон с записями длиной до часа, и выяснилось, что - опять же условно - на разных версиях оси разный предел максимального размера файла и предел этот строго эмпирический, нигде четко не описан. .amr файл длиной в час занимал сильно больше этого лимита, и в итоге нам на пустом месте пришлось делать индекс частей записи и соединять их между собой уже при отправке на сервер.
Сеть
В 2026-м году человек, сказавший “открыть HttpConnection это крайне сложно” будет выглядеть слегка ненормальным. В случае BlackBerry чтобы открыть соединение библиотеки писались годами.
При открытии соединения надо было скинуть устройству строчку, идентифицировавшую тип соединения. А типов было несколько:
- Direct TCP (он же мобильная сеть). Кстати, руками поставь APN, который автоматически определяется далеко не всегда.
- WiFi (два вида, уже не вспомню, какие именно)
- BES/BIS, они же BlackBerry Enterprise Service и BlackBerry Internet Service
- MDS (Mobile Data System, что бы это ни значило)
Естественно, чтобы разработчику было больнее, методы, определявшие активность того или иного соединения, нормально не работали, так что в самом конце приходилось пробовать открывать короткий тестовый коннекшн на какой-нибудь условный Google. Кстати, если он не отработал, то:
- Возможно BIS, BES и прочие MDS были настроены через одно место (например, тупо не поддерживали https. Да и правда, а зачем?
- Возможно, у провайдера стояла HTML-страничка на первый вход в интернеты (потом мы научились ее руками отлавливать и открывать вебку чтобы юзер мог кликнуть кнопку Next и выйти уже в интернеты)
- Возможно миллиард других причин потому что гладиолус
Чтобы разработчику было еще больнее стоковый HttpConnection тупо не умел заливать крупные файлы. Официальная документация говорила примерно так - если тебе надо залить крупный файл, побей его на мелкие куски и собери обратно на сервере. Не можешь? Ну кури бамбуки, что уж там.

Я до сих пор горд что написал под Evernote свой HTTP over Socket который с помощью магически подобранных флагов сокета и прочей темной магии умел лить мегабайты одним куском. Flush? Я ж сказал, не получится - первый же флаш закрывал соединение. У меня кстати, не закрывал.
Старики вспомнят, что потом - ну опять же, когда платформа была уже при смерти - Blackberry выкатил API с автоматическим определением лучшего соединения.
Оно было. И оно так же падало после первого flush. Но мы и его использовали - компонент для открытия соединения тогда стал еще толще.
Ну а чтобы добить уже этого самого разработчика, инфра каждого сотового оператора работала непредсказуемо. Я знаю о чем говорю - четыре года я разгребал баг-репорты со всего мира, ровно половина из которых сводилась к письмам провайдеру с тектстом вроде “Дорогой сэр, не будете ли вы столь любезны включить HTTPS?”
Все работает только в документации
Как-то раз Соло пришла в голову крайне опасная идея - у заказчика сервака нормального нет, делать он его не готов, с прыжками вокруг соединения мы задолбались, а что если пересылать файло кусками через email, а на блэкберевом бэке собирать все это (кажется, плагином)? Все бы ничего, но встроеный эмулятор такого флоу работал только на бумаге и то по воскресеньям. Мы убили месяц, в итоге пришлось допинать заказчика сделать нормальный бэк. Через год еще по штрафу огребли - в первый и последний раз на моей памяти. Не то чтобы я тогда был сильно против, но кажется после этого я рявкнул что еще один такой прикол, и я положу заявление на стол. Больше штрафов не было.
В Evernote мы использовали стандартный компонент браузера для отображения отрендеренных заметок. Стандартный браузер падал в крэш при попытке загрузить заметку с HTML размером примерно 2Мб. Или 4, не вспомню уже. HTML был корректный, все было написано корректно, просто thread браузера падал, в какой бы асинхрон мы не уводили загрузку и что бы с ней не делали. Вместе с ним, кажется, падало и приложение.
В итоге в конце таких заметок была кнопка “Сорян, не получится, вот тебе превьюха и грузи на веб-версии, спасибо, пака”.

java -source 1.3
Никаких коллекций. На тебе Vector и HashSet и вперед. java.regexp? Окстись, какой тебе регэксп. Ручками все, ручками. Ну, почти - у меня был свой личный кусок с относительно нормальными коллекциями, java.regexp и еще пачкой разного, портированный из Java 1.6 путем недельного вырезания дженериков и JNI. Когда я в запустил тестовую регулярку и распечатал в консоль корректный результат (первый же запуск после удаления последнего красного куска в 2к файлов), я чуть не прыгал от восторга. Если ты думаешь, что я не слишком нормален - посмотри начало поста, а потом читай . Для всего есть причина.
JNI? Какой такой JNI?
А его не было. Нам, помнится, надо было перегонять .amr в speex. Ну, такое требование - бэк у заказчика был под приложение для Windows Mobile, которое делал тоже я, и там легко, быстро и непринужденно мы на лету конвертировали .amr в speex. Всего-то плюсовая либа и вот - мелкий, удобный для работы файл. Здесь даже для того, чтобы просто записать кусок на файлуху, приходилось держать очередь на пару секунд звука, ибо запись шла с такой задержкой (как мы изьебывались чтобы этого не было видно - это отдельная долгая история). Что уж тут говорить про конвертацию - помнится, proof of concept дело делал, но работал раз в двадцать медленне референса на плюсах. В итоге конвертацию мы скинули на момент перед закачкой файла, а редактировали запись с помощью записанных и индексированных .amr (ну да, у нас там была не только перезапись, но еще и вставка в произвольное место часового файла).
Быстро? Какое там быстро?
Как-то раз нам надо было сделать экран в приложении, который парсил VCARD контакта и бурно его отображал. За одним позволял редактировать и вот это самое.
Со стандартными контролами экран скроллился по пикселю в секунду. Нет, мы не грузили его чем-то случайно. Нет, там не было тяжелых тредов в фоне. Мы просто кидали ему пачку стрингов и рисовали. На этом все. Ну, может быть пара рисукнов, и то не особо крупных.
В итоге мы отрисовали страницу целиком на графиксе с double bufferом и обновлениями видимого куска экрана. Ну, в смысле, я реализовал. Это было больно, но зато экран скроллился легко и непринужденно. Именно тогда я познал магию периодического мелкого System.gc(). Зачем? Ну затем, что память засиралась влет даже при корректном использовании и тяжелый gc мог устроить буйное веселье. А мелкий работал тихо и не жужжал. Естественно, это все плохо и неправильно. А что делать-то, если иначе было никак?
Круто быть сеньором, но не блэкберревым
В какой-то момент я остался единственным разработчиком, который написал действительно много проектов на Blackberry и мне стали ожидаемо скидывать их поддержку, новую мелочь из прилетавшего от заказчиков и так дальше. Я начал грустить - все остальные уже жили в раю с нормальной жабой, ну или на худой конец Objective-C. Я дошел до края - я начал тосковать по Windows Mobile 2003.

В какой-то момент Соло понял, что я загрустил уже окончательно и кинул мне пару проектов, на которых я хотя бы пару дней в неделю отдыхал от бесконечных тикетов по Evernote.
Смерть
BlackBerry умирал долго. С попытками переформатироваться, сделать крупные экраны, приделать тач, портануться на QNX, чего только не было. Но умер все равно. Сначала серьезные парни стали покупать себе айфоны с лозунгом “ну у меня все равно есть BlackBerry, на нем печатать удобнее”. Айфоны тогда они стыдливо прятали в карман и доставали с извиняющимся видом - мол, не могу противостоять прогрессу, вы же понимаете.
А потом BlackBerry просто исчез. А я в какой-то момент сказал, что больше никогда не напишу ни строки кода под него, пусть меня лучше уволят.
