Условности
Должен оговориться о том, что язык Kotlin я не знаю вообще, и у меня не было цели в данном "эксперименте" его изучить (Багаж языков за спиной итак не мал). Я не видел раньше части кода на Kotlin, не читал книг и статей о нем. Мой разум перед этим языком чист, как и Ваш перед этой статьей.
Почему так?
Ну... во-первых - изучать на ходу что-то весело. Во-вторых - только будучи неосведомленным - получаешь больше всего "приключений" на свою 5-ю точку (и довольно болезненный, но качественный опыт ;D ). В третьих - "почему бы и да, собственно"? Имею я право взять Android Studio и писать с нуля на языке, который мне неизвестен? Конечно имею!
Должен сказать, что это не гайд, а просто обзор на то, с чем я не сталкивался ранее.
Тут я расскажу историю, покажу что было, получалось (и не получалось тоже).
Расскажу какую-то полезную информацию, но весь код и полный пройденный путь я не выложу.
Воспринимайте это - как "цирк одного клоуна" и просто получайте удовольствие. ;)
Почему Kotlin?
Вообще, по факту - я хотел написать свое (довольно простое) приложение, а на чем - мне как-то "до фонаря".
Из слухов я был в курсе, что Google пытается продвигать Kotlin на замену Java (и довольно давно). И я подумал - нужно попробовать. Заодно и сравню с Java. Стал ли язык проще и лучше, чем Java для Android?
Уточню, что Android приложения мне писать уже доводилось на Java. Это было 3-4 года назад, когда я работал программистом. Но в то время в компании, на которую я работал - решили, что Kotlin еще молодой и может "накрыться медным тазом" в любой момент. Потому никто его кандидатуру даже не рассматривал. Так что писал я чисто на Java.
Время проверки настало! ;)
Какое приложение то?
Недавно я написал простое Web приложение для себя, напоминающее записную книжку. Принцип в том, что я просто и быстро сохраняю текстовые данные в нем, а найти что либо могу как в Яндексе - по ключевым словам или части слова из заголовка и содержания. Выглядит оно так:
Данные свои я затер, так как активно пользуюсь своим приложением.
Мда, я не Web дизайнер, вид максимально простой. Зато, все по функционалу (Да, может быть я и оправдываюсь). xD
Ну, для записей пойдет, главное чтобы быстро открыл - записал информацию (и сразу забыл, такая вот внешняя долговременная память), а что нужно - моментально нашел. ;)
И вот, через браузер с компьютера записывать то удобно, но с телефона - полнейший ад! :0
А именно телефон - интимная вещь, которую мы берем с собой повсюду, даже в туалет. И возможность быстро записывать что угодно и откуда угодно - меня привлекала. И я начал действовать!
Вы, наверное, подметите, что - есть же куча приложений с облаком, web сайтами и тд. А я Вам скажу... - "Нет!"...
Шучу. xD
Безусловно, таких приложений много, но я немного параноик и не хочу доверять свои данные всему и вся (Кто знает, какие люди разрабатывали приложение или сервис), а писать я буду туда и пароли.
К тому же - у меня есть свой сервер - так почему бы не добавить ему немного работы? (Рассуждаю, как типичный начальник, блин) ;)
Принцип работы приложения
Писать код без плана - признак бесконечного кодинга, а мне этого не надо. У меня был четкий план и я его придерживался!
Исчерпывающе рассказал? xD
Ладно, в сторону шутки - давайте о принципе работы поговорим:
- У нас есть сервер Linux (на нем сайт работает) + Apache (является движком сайта) + PHP ( генерирует и выдает страницы сайта) + MySQL(База данных - где хранятся данные сайта). В простонародье вся эта "солянка" называется - LAMP;
- PHP отвечает за RestAPI (Что это - объяснено ниже в статье после списка);
- В качестве данных - используются JSON строки (тоже объяснение и пример ниже);
- Каждую функцию выполняют разные PHP файлы (add.php - добавляет, del.php - удаляет. Все просто!);
- У базы данных MySQL есть всего 2 таблицы - users и texts. В users - записаны зашифрованные данные авторизации (чтобы даже получив доступ к базе данных - Вы не смогли получить логин и пароль). В texts: заголовки; содержание записей; даты создания; ссылки на пользователей, написавших текст (их id) и пометка - удалена ли запись, - чтобы удаленные записи можно было потом восстановить в случае чего;
- В приложении имеется всего 3 окна (Activity, Активности, страницы и тд.): "Авторизация", "список записей с поиском" и "редактирование записи". Во втором и третьем окне есть вверху кнопки и выпадающее меню;
- Регистрация не предусмотрена, так как это приложение "для себя" и родных. регистрировать я буду сам вручную генерируя шифр в самой базе данных.
Это весь принцип моего приложения.
"А сейчас дети, минутка RestAPI для самых маленьких" xD
RestAPI - в "практическом смысле" - это сайт, который получает от нас данные в виде JSON или XML строк и отвечает нам тем же. А что делает он с этими данными - прописано в коде PHP.
Исторически так сложилось, что существуют следующие запросы: GET, POST, DELETE, PUT и тд. Но большинство из этих запросов стали рудиментами для IT (чем-то уже не сильно нужным). В RestAPI используются в основном GET и POST запросы.
GET (от слова "получить") - запрашивает данные у сайта. Для практики откройте браузер и напишите в строке сайта https://yandex.ru/search/?text=test&lr=11207 , и Вы получите ответ от Яндекса на запрос "test".
Это и есть GET запрос. В нем Вы указываете сайт (доменное имя https://yandex.ru), путь до функции (папка с файлом php /search/), функцию (по совместительству файл php. Здесь не указан, так как по умолчанию index.php не указывается. И не известно, использует ли Яндекс - PHP, но если бы использовал, можно было бы написать https://yandex.ru/search/index.php).
Затем указана переменная "?text=" (имя переменной зависит от логики RestAPI) и чему она равна (в нашем случае "test". И да - знак вопроса "?" - указывает, что начались переменные). Тут мы и указали, что Яндексу надо найти.
Затем указывается знак "&", говорящей о следующей переменной и сама переменная со значением - "lr=11207".
Что значит эта переменная - я не знаю, это вопрос к разработчикам Яндекса. ;)
POST запрос (от слова "опубликовать") сложнее. В основном его используют для отправки данных на сервер.
Он шифруется (этим безопаснее, но перехватив пакеты данных - тоже вполне дешифруемый) и мы не можем его написать в строке сайта, но зато вполне получится применять в формах html (GET запросы тоже можно делать с их помощью).
В своем коде я буду использовать исключительно POST запросы, так как в нем имеется авторизация и данные авторизации нужно прятать от лишних глаз (а так же передавать с каждым запросом).
JSON - это строка текста, в которой перечисляются данные в виде "ключ - значение", например "имя"(это ключ) - "Вася"(это значение), "возраст" - 50 и тд. Наглядный пример строки указан ниже на изображении. Таким методом мое приложение и будет общаться с сервером. ;)
Как все начиналось
Была ночь. Мои глаза были как у енота. Я воодушевленный, решил приступить. Моим спутником в деле был кофе "3 в 1". Мне нужна была Android Studio...
Если Вы читали другие мои статьи, то знаете, что я использую Linux Lubuntu 16.04, который сейчас морально устарел, но выдает хорошие результаты производительности (за что я его очень ценю).
По этой причине ставить новую версию Android Studio в мой Linux было - "геморным" решением и я от этого сразу отказался.
Я открыл FlatHub и спокойно поставил последнюю версию Android Studio не напрягаясь. Все завелось "из коробки". Чудеса, да? ;D
Ну, я не долго думая - создаю проект, открываю Android Virtual Device Manager (AVD, менеджер виртуальных устройств), подключаю свой телефон (чтобы сэкономить ресурсы компьютера без виртуалки) и понимаю, что данный прикол не пройдет. xD
FlatPak имеет немного свою собственную среду Linux системы (каждое приложение - контейнер), с новыми библиотеками, которые опосредованно контактируют с моим Linux. Как прокинуть мое устройство туда? Как сказал великий классик - "а хрэ его знает!".
По "майдохавшись" продолжительное время, я понял, что на данный момент без виртуалки не обойтись (Если Вы знаете, как это исправить - подскажите в комментариях, я буду премного благодарен, так как еще планирую по писать приложения). :)
Смирившись с тем, что придется использовать виртуальное устройство - я создал виртуалку Android 9, которая не запустилась (кто бы, блин, сомневался xD ).
Я не стал долго разбираться. Удалил Android 9, создал Android 10 и все завелось.
"Поехали!" - воскликнул я, пока не осознал, что Android Studio скорее ползет, чем едет. Да еще и "вкушает" по пути много оперативной памяти.
Ну, я изначально был морально готов к этому! Я знал на что иду, так что запас терпения мой был как у "Будды". Я терпеливо ждал...
Потом все же решил попробовать оптимизировать среду разработки. Залез в Яндекс, нашел это:
Если по русски - то нужно открыть файл studio64.vmoptions в папке с Android Studio и вставить текст, написанный в квадратике. Если что - путь у Flatpak до Android Studio - "~/.var/app/com.google.AndroidStudio/config/Google/AndroidStudio2021.3", может кому нужно. :)
Ну, я и вставил. После этого Android Studio не запустилась. Ругалась на Xmx4096m. Я немного поправил эти параметры и теперь рабочий вариант выглядит так:
И да. Среда разработки стала по шустрее (пока не запустишь виртуальную машину Android 10, которая помимо выделенных 1024 мегабайт оперативной памяти - съедает еще поверх оперативку).
Я так же решил, что 1024 мегабайт ОЗУ для Android 10 - жирновато, пускай худеет до 512 мегабайт. Я не такое уж и тяжелое приложение пишу! ;D
И знаете, работать стало вполне комфортно, даже можно было плюсом открыть до 10 вкладок браузера (ну, если учитывать, что у меня с недавних пор в ноутбуке 8 гигабайт ОЗУ. Если же у Вас 4 гигабайта - забудьте о виртуалках! Я серьезно! xD ).
После настроек Android Studio я занялся проектом.
Так уж сложилось, что создав первый проект - я банально не смог его запустить ("из коробки" причем). Он ругался на непонятную "хрень" (по типу - не могу компилировать на Android API 32). Решилось созданием нового проекта с галочкой "Поддержка старых устройств".
Да, привыкайте - все решается просто заменой. "Я у мамы мастер - ломастер. Дайте кувалду - забью болт в резьбу!" xD
Сам процесс
Стадия медитации
Я не сразу начал строчить код на Kotlin. В первую очередь - отредактировал первое Activity, чтобы можно было ввести логин и пароль, а затем нажать кнопку "Войти".
Правда, зачем-то изначально я создал 2 кнопки - "Войти" и "Авторизоваться" (хотя планировал кнопку "Зарегистрироваться"). Почему планировал? Сам не знаю. Изначально была задумка, что регистрации нет. Во я клоун! xD
В общем, после настройки Activity - я спокойно запустил приложение на эмуляторе. Все складывалось хорошо.
Activity - это, конечно, хорошо. Но толку то от него, если кнопка "Войти" - ничего не делает! Потому я полез в Яндекс.
Да, я не перешел в код Kotlin сразу, так как понимал, что сейчас мои знания равны 0 и мне там ловить нечего.
Стадия катарсиса
Зайдя в Яндекс - начал искать способы отправки RestAPI запросов, и наткнулся на 2 библиотеки - это GSON (Для обработки JSON строк) и Retrofit2 (для отправки запросов и получения ответов).
Нашел несколько статей с уроками по использованию этих библиотек в связке и эти статьи не дали мне нужного результата (бесило, кстати, что они были слишком похожи по принципу).
Начнем с того, что код, представленный в статьях - излишен (Simply - не значит просто, по их мнению x( ). Почему я так считаю?
Вот представьте, что Вы пришли в магазин и просите продавца показать Вам компьютеры, а он вместо того, чтобы просто дать Вам посмотреть на компьютеры и их характеристики - начинает заливать о правильности чистки каждого из этих компьютеров (причем методичные примеры дает, все по ГОСТ-у).
Вам для задачи (купить компьютер, если Вы забыли - зачем пришли после его рассказа xD) - нафиг эта информация не сдалась.
Тут аналогичная ситуация. Мне нужно сгенерировать JSON строку и отправить POST запрос с получением JSON строки от сервера. Нахрена мне создавать "Kotlin Data Model Class" (Модель данных класса Kotlin). Что это за модель? Скажем так - Вы в этой модели объявляете те переменные, которые получаете от POST (ну или GET) запроса. То есть по этой модели - будет читаться Ваша JSON строка, переданная от сервера.
Google - сложно о простом, блин!
Вы скажите - так это же удобно. Типы ты заранее заготовил модель чтения. А я скажу - это нифига не удобно. Я должен плодить 100500 классов (отдельных файлов Kotlin) для того, чтобы читать данные (Один чих POST запроса - один файл с классом. Кто знает - сколько запросов я буду делать к серверу?). А я всего-лишь хочу получить JSON строку и прочитать в ней данные, нужные мне в тот или иной момент. Более того, в примерах нигде не указано - как передать данные с POST запросом, зато как получить - "хоть утони"!
Тем не менее, при помощи еще одной статьи, где объяснялось, как правильно сделать эту модель (с учетом возвращения пустых значений) я таки сделал GET запрос (для начала) к серверу (заведомо его набросав на PHP).
И знаете что произошло? GET запрос не сработал. А причиной был GSON с его чтением модели.
Я долго мучился с этим, не понимая - почему у меня не возвращается запрос в принципе (было ощущение, что и запроса к серверу не было) и я решил переформулировать запрос к Яндексу.
Настоящие Android разработчики - можете на до мной посмеяться. В принципе, есть за что. ;)
Я написал "Kotlin Android POST запрос String". И знаете что? Почитав форумы - я понял, что вместо подстановки той же модели - можно просто указать <String> в GET запросе и получить строку (А потом и POST запрос легко стал понятен). И (о, чудо) - я получил свою строку. И я "дропнул" (выбросил) GSON. А прочитать значения в этой строке можно при помощи функции JSONObject(s:String), что весьма эффективно, очевидно, работает и не требует создания 100500 классов.
Вот почему у меня столько "бугурта". Я не против, что меня пытаются научить "правильным" структурам кода в Android Studio Kotlin (да и Java тоже). Мне не нравится, что мне, как программисту - не доверяют и не дают решать задачу логично и по своему усмотрению (в структуре, которая "правильная" - очень легко потеряться. Логика очень странная).
Я не Android разработчик. Я пишу код обычно под ПК и я могу придумать несколько способов превратить строку JSON в удобоваримые данные (даже без сторонних библиотек), но тут мне и строку получить не давали.
Я должен высказать отдельное спасибо разработчикам Android Studio за функцию превращения кода Java (вставленного откуда-то) в код Kotlin. Как вставите код - он сам переделается в Kotlin. Это реально очень спасало, так как на языке Kotlin - мало информации с форумов, а на Java - "вагон и маленькая тележка". :)
В общем, самое сложное - было позади. :)
Стадия fun-а
Весь остальной код - я отправлял, читал данные, открывал, закрывал разные Activity, настраивал тему оформления, генерировал динамические кнопки.
Остальной процесс был прост, хоть и забавен.
А сейчас я расскажу об особенностях Kotlin как языка, которые я подчеркнул для себя в процессе.
1. Уставший я - несколько секунд всматривался в слово fun в коде и ловил себя на мысли "блин, счастливая функция". fun (function, функция). Это не привычно, но забавно. Любая функция начинается в Kotlin со слова fun. ;)
2. Переменные в Kotlin бывают 2-х типов: var (variable - переменная. Можно и читать, и редактировать) и val (value - значение. Можно только читать, редактировать нельзя), к чему приходится привыкать (Сначала я тупил с этим, но Android Studio сама мне сказала о том, что чтобы редактировать переменную - нужно из val сделать var. Опять спасибо разработчикам Android Studio, даже гуглить не пришлось). :)
3. Объявление типа переменной стоит в обратной стороне от Java. например в Java: int x = 0; В Kotlin: x:int = 0. И точка с запятой на конце строки не ставится (это прям ломка для меня xD ).
4. Если объявленная переменная не имеет значения - нужно указать слово lateinit (Что ставит значение по умолчанию).
5. Вместо указания this как контекста - нужно указывать this@"название Activity". Пример: this@DataEditorActivity.
6. Чтобы указать класс Activity, на который Вы хотите перейти - нужно указать, что он является Java классом. Пример: DataListActivity::class.java
Вот такие особенности хорошо заметны во время написания кода. Но в целом - не покидает ощущение, что Kotlin - это просто "нашлепок" на Java (если уж нужно указывать, что класс от Activity - это класс Java).
Из слухов, я слышал, что на Kotlin тяжелые тонны кода от Java стали более компактными и простыми. Сам я подобного не заметил. Что на Java писал "простое на сложном", что на Kotlin. Разницы не заметил вообще. Но это мое субъективное восприятие, так как о самом Kotlin я пока ничего не читал. ;)
Ах да, вот что у меня в итоге получилось:
Заключение
Плох ли язык Kotlin? Нет. Показался ли он лучше Java? Тоже нет. Сложный? Да не сказал бы. Язык - как язык, ничего особенного. Как ты зарезервированные слова в коде не указывай - суть языка не изменилась. Ощущения от него такие же как от Java.
Получил ли я удовольствие от написания кода? Да. Было ли сложно? безусловно.
Как бы там не было - результат есть и я так же буду использовать Kotlin и в следующих проектах. Почему бы и нет?
Если Вы дочитали эту статью - спасибо Вам. Сложно уместить в статью весь путь написания кода. Я старался. А получилось ли у меня - решать Вам. :)