Инструкция: устанавливаем Windows Subsystem for Android на любой сборке Windows 11
Несколько дней назад Microsoft начала тестирование подсистемы Windows Subsystem for Android (WSA), которая позволяет запускать Android-приложения в Windows 11.
Сейчас функция доступна только участникам программы Windows Insider на канале Beta, что несколько удивительно, так как обычно все новшества вначале появляются на канале Dev. Но даже если вы используете канал Beta, то для установки подсистемы из Microsoft Store потребуется сменить регион на США в самой Windows 11.
Microsoft обещает, что инсайдеры на канале Dev также вскоре получат доступ к Windows Subsystem for Android, но какие-либо конкретные сроки не называются. Если вы не хотите ждать, то можете установить подсистему вручную. Для этого вам потребуются прямые руки и небольшие навыки работы в PowerShell.
Важно! Все действия вы делаете на свой страх и риск.
Благодарим aleks242007 и участников чата Community в Telegram за помощь в составлении инструкции.
Инструкция
Установка Windows Subsystem for Android
- Для начала убедитесь, что ваш компьютер поддерживает виртуализацию. Для этого откройте «Диспетчер задач», перейдите на вкладку «Производительность», выберите CPU и посмотрите текст под графиком. Там должно было указано: «Виртуализация: Включено».
- Если виртуализация отключена, то вам необходимо включить её в BIOS. У разных производителей настройка может располагаться в разных разделах и называться по-разному, так что можно поискать информацию в Google для вашего конкретного устройства.
- Если в BIOS настройка отсутствует или значение в «Диспетчере задач» не меняется, то вы вряд ли сможете запустить Windows Subsystem for Android на своём компьютере.
- Следом откройте меню «Пуск», введите в поле поиска «Включение или отключение компонентов Windows» и выберите соответствующий результат.
- В открывшемся окне установите галочку напротив пункта «Платформа виртуальной машины», нажмите «ОК», дождитесь применения изменений и перезагрузите ПК.
- Далее нам потребуется скачать установщик Windows Subsystem for Android в формате MSIXBUNDLE с сервера Microsoft Store:
- Перейдите на сайт Microsoft Store — Generation Project (от rgadguard) по этой ссылке.
- В поле на сайте вставьте следующую ссылку:
- Справа от поля в выпадающем меню выберите Slow и нажмите на галочку.
- В появившемся списке найдите файл с примерно таким названием (номер версии может отличаться):
- Нажмите на название этого файла и сохраните файл в любой папке на вашем компьютере. Обратите внимание, что файл должен быть в формате .MSIXBUNDLE. Если это не так, то просто смените расширение файла на нужное. Файл должен весить примерно 1,2 ГБ.
- Запустите PowerShell или Windows Terminal (нужна вкладка с PowerShell) от имени администратора.
- Введите в консоль следующую команду:
- «C:\Users\user1\Desktop\MyApp.msix» — путь к файлу MSIXBUNDLE, сохранённому на шаге 4. Чтобы быстро его получить, вы можете нажать правой кнопкой мыши по файлу в «Проводнике» и выбрать пункт «Копировать как путь».
- Решение ошибки:
Если вы увидели такое сообщение в PowerShell, то введите следующую команду:
После этого вновь введите команду Add-AppxPackage из шага 6.
- Нажмите Enter и дождитесь завершения установки.
- Если всё прошло успешно, то в меню «Пуск» появится приложение под названием Windows Subsystem for Android.
Установка APK-файлов
Теперь подсистема Windows Subsystem for Android работает, однако с установкой приложений есть некоторые сложности. Как вы уже знаете, вместо Google Play здесь используется Amazon Appstore. Причём отображаются там лишь приложения, которые Microsoft и Amazon протестировали на работоспособность в подсистеме.
Правда воспользоваться Amazon Appstore всё равно не получится. Приложение не только требует учётную запись Amazon, но и проверяет ваше местоположение. Можно, конечно, подключить VPN, но есть ли в этом смысл?
К счастью, Windows Subsystem for Android поддерживает установку приложений с помощью APK-файлов. Вы можете воспользоваться либо утилитой WSATools, о которой мы рассказали в статье по этой ссылке, либо устанавливать вручную с помощью командной строки по инструкции ниже.
- Скачайте SDK Platform Tools для Windows с сайта Android, перейдя по этой ссылке.
- Извлеките папку platform-tools , например, в корень диска C (рядом с папками Windows, Program Files и т. д.)
- Откройте приложение Windows Subsystem for Android и включите «Режим разработчика».
- Нажмите на кнопку рядом с элементом «Файлы». Начнётся запуск подсистемы Windows Subsystem for Android.
- Нажмите на кнопку «Обновить» рядом с элементом «IP-адрес».
- В описании для элемента «Режим разработчика» появится IP-адрес, который мы будем использовать для подключения к подсистеме с помощью ADB.
- Откройте командную строку (или Windows Terminal) и перейдите в папку с установленным SDK Platform Tools, подставив нужный путь к папке:
- Введите следующую команду, подставив в неё IP-адрес из предыдущего пункта:
Примечание. Если выполнять команды через PowerShell, то перед ADB следует прописать ./
Чтобы быстро скопировать путь к файлу, нажмите по нему правой кнопкой мыши и выберите «Копировать как путь». Затем вставьте его после adb.exe install и нажмите Enter.
Поделиться впечатлениями о работе Windows Subsystem for Android и обсудить сценарии её использования вы можете в нашем чате в Telegram. Там же можете задавать вопросы, если возникли какие-либо сложности с установкой подсистемы или Android-приложений.
Поскольку далеко не все Android-приложения корректно работают в подсистеме, пользователи решили составить таблицу с информацией о работоспособности приложений в WSA. Найти и внести свой вклад вы можете на GitHub.
Источник
Методы лечения различных ошибок в Android Studio при разработке проекта
Сегодня хотел бы поделиться своим анализом и способами лечением разных ошибок при разработке своего продукта в Android Studio. Лично я, не раз сталкивался с различными проблемами и ошибками при компиляции и/или тестировании мобильного приложения. Данный процесс, всегда однообразный и в 99% случаев и всегда нужно тратить n-колличество времени на его устранение. Даже, когда ты уже сталкивался с данной проблемой, ты все равно идешь в поисковик и вспоминаешь, как же решить ту или иную ситуацию.
Я для себя завел файлик, в котором отметил самые частые ошибки — потратив на это несколько часов и перечислил самые популярные ошибки (в дальнейшем планирую просто их запомнить), чтоб сократить свое время в дальнейшем.
Итак, начну по порядку с самой распространенной проблемы и дальше буду перечислять их по мере появления:
1) Если подчеркивает красным код, где используются ресурсы: R. — попробовать (но вероятно не поможет): Build -> Clean Project.
В принципе на Build -> Clean Project можно не терять времени, а лучше всего — слева переключиться на Project, открыть каталог .idea, затем каталог libraries и из него удалить все содержимое. Затем нажать кнопку Sync Project. А затем (если все еще красное, но скорее всего уже будет все ок ) Build -> Clean Project.
2) После внезапного выключения компьютера, после перезапуска может быть во всех проектах весь код красным. Перед этим может быть ошибка: Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of ‘adb version’. Есть три решения — первое помогло, второе нет (но может быть для другого случая), а третье — не пробовал:
а) File — Invalidate Caches/Restart — Invalidate and Restart
б) Закрыть студию. В корне папки проекта удалить файл(ы) .iml и папку .idea. Вновь запустить студию и импортировать проект.
в) Нажать Ctrl-Alt-O и запустить оптимизацию импорта.
Кстати, adb сервер можно проверить на версию (и работоспособность) и затем перезапустить:
3) Если Android Studio выдает приблизительно такую ошибку: Error:Execution failed for task ‘:app:dexDebug’.
Надо слева переключиться на опцию Project, найти и удалить папку build которая лежит в папке app, т.е. по пути app/build. Затем перестроить весь проект заново: Build -> Rebuild Project.
Такое же решение если ошибка типа: «не могу удалить (создать) папку или файл» и указан путь, который в ведет в app/build. Тоже удаляем папку build и ребилдим проект.
4) В сообщении об ошибке упоминается heap — виртуальная память. А ошибка обычно вызвана ее нехваткой, т.е. невозможностью получить запрашиваемый объем. Поэтому этот запрашиваемый объем надо уменьшить, т.е. переписать дефолтное значение (обычно 2048 MB которое можно изменить в настройках), на меньшее 1024 MB.
В файле проекта gradle.properties пишем:
5) Android Studio пришет примерно такую ошибку: Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to «83648b99316049d63656d7276cb19cc7e95d70a5»
Возможные причины (кроме необходимости регулярного обновления SDK):
а) Загруженный проект был скомпилирован с помощью уже несовместимого старого gradle плагина. В этом случае надо найти и подключить в своем build.gradle проекта этот более старый плагин. т.е. попробовать более старые версии, например: 1.1.3 (часто именно 1.1.x и подходит).
Найти все версии можно здесь.
б) Если в build.gradle проекта используется beta-версия плагина — это означает, что срок ее истек. Посмотреть последние релизы (продакшн и бета) можно также здесь:
6) Иногда при подключении сторонних библиотек могут дублироваться некоторые файлы (обычно связанные с лицензированием). В сообщении будет что-то содержащее слова: duplicate files. Решение — надо посмотреть в сообщении об ошибке или в документации подключенной сторонней библиотеки — какие именно файлы стали избыточными, и перечислить их в build.gradle модуля для исключения (exclude) из билда.
Это делается в директиве packagingOptions (которая, в свою очередь, находится в директиве android).
Источник
Некоторые “подводные камни” разработки под Android
Недавно наша команда завершила разработку приложения под Android. В процессе разработки и затем поддержки мы столкнулись с некоторыми проблемами технического характера. Часть из них — это наши баги, которых мы могли бы избежать, другая часть — это совсем неочевидные особенности Android, которые либо плохо описаны в документации, либо не описаны вообще.
В этой статье я бы хотел рассмотреть несколько реальных багов, которые возникли у наших пользователей и рассказать о путях их решения.
Статья не претендует на подробный анализ потенциальных проблем, это просто рассказ из жизни одно реального Android приложения.
RTFM (http://en.wikipedia.org/wiki/RTFM)
Так как при разработке под Android надо иметь в виду, что ваше приложение может работать на огромном количестве различных устройств, то надо думать о проблемах их совместимости.
Вот например одна из ошибок, которая возникала у наших пользователей:
А причина — проста, согласно документации класс android.util.Patterns доступен начиная с версии API 8 (Android 2.2.x), а у пользователя была версия 2.1. Решили мы это конечно оберткой этого кода в try/catch .
Вот еще одна подобная проблема вызванная невнимательным чтением документации:
Все дело в том, что strict mode (http://developer.android.com/reference/android/os/StrictMode.html) был включен по умолчанию в Android начиная с версии 3.0. Это значит, что ваше приложение не может обращаться к сети напрямую из основного UI потока, так как это может занимать некоторое время и при этом основной поток блокируется и не отвечает на другие события. Мы старались избегать подобного поведения, но в одном из мест все-таки остался простой сетевой вызов. Решена эта проблема была тем, что мы вынесли этот код в другой поток.
Поворот устройства — что может быть проще и привычнее для пользователя?
Казалось бы, для мобильных устройств смена ориентации экрана — это вещь настолько часто используемая и привычная, что это должно отразиться и в API. Т.е. эта ситуация должна обрабатываться очень просто. Но нет. Тут много нюансов.
Допустим, что нам необходимо сделать приложение, которое загружает список чего-либо и выводит его на экран. Т.е. при старте Activity (в методе onCreate() ) мы запускаем поток (чтобы не блокировать UI поток), который будет загружать данные. Этот поток отрабатывает некоторое время, поэтому мы будет отображать процесс загрузки в ProgressDialog . Все просто и замечательно работает.
Но, после загрузки, пользователь повернул устройство и тут мы обнаруживаем, что снова появился ProgressDialog и мы опять загружаем наши данные. Но ведь ничего не изменилось? Просто человеку удобнее смотреть на этот список повернув устройство.
А все дело в том, что метод onCreate() вызывается не только при создании Activity , но и при повороте экрана! Но мы не хотим засталять пользователя снова ждать загрузки. Все что нам надо — это снова показать уже загруженные данные.
Если мы поищем в интернете, мы найдем много ссылок на описание этой проблемы и также огромное количество примеров как решить эту проблему. И что самое плохое, что большинство таких ссылок предлагает неверное решение. Вот пример этого — http://codesex.org/articles/33-android-rotate
Не делайте обработку поворота экрана через onConfigurationChanged() ! Это неверно! Официальная документация ясно утверждает что “Using this attribute should be avoided and used only as a last-resort.“ http://developer.android.com/guide/topics/manifest/activity-element.html#config
А вот правильный подход описан здесь — http://developer.android.com/guide/topics/resources/runtime-changes.html И как показывает практика — он не прост в имплементации.
Идея в том, что перед разворотом экрана Android вызовет метод onRetainNonConfigurationInstance() вашего Activity . И вы можете вернуть данные (например список загруженных объектов) из этого метода, которые и будут сохранены между 2 вызовами метода onCreate() вашего Activity . Затем при вызове onCreate() вы можете вызвать getLastNonConfigurationInstance() который и вернет вам сохраненные данные. Т.е. при создании Activity вы вызываете getLastNonConfigurationInstance() и если он вам вернул данные — то эти данные уже были загружены и надо только отобразить их. Если же не вернул данные — то запускаете загрузку.
Но вот на практике ситуация выглядит так. У нас может быть 2 варианта когда пользователь поворачивает устройство. Первый вариант — когда идет загрузка данных (работает наш поток который загружает данные и при этом отображается ProgressDialog ) или данные уже загружены и мы сохранили их в списке для отображения. Получается, что в первом случае мы при повороте должны сохранить ссылку на работающий поток, а во втором случае ссылку на уже загруженный список. Мы так и делаем.
Но это усложняет наш код и не кажется мне простым и интуитивным. Более того, когда идет смена ориентации экрана и мы сохранили поток загрузки данных, мы потом вынуждены при onCreate() опять восстанавливать ProgressDialog ! А если добавить сюда, что в нашем приложении пользователь может загружать данные из разных мест и у нас не один поток загрузки данных, а несколько — то количество кода которое обслуживает простой поворот экрана становится просто огромным.
Честно сказать, я не понимаю почему это было сделано так сложно.
Чуть более подробнее о потоках или использование AsyncTask.
Давайте рассмотрим загрузку данных в другом потоке чуть более подробно, так как и при этом нас ждали неожиданные “сюрпризы”.
Немного теории: для облегчения создания и работы в потоке отличном от основного UI потока был сделан специальный класс — AsyncTask (http://developer.android.com/reference/android/os/AsyncTask.html)
Суть его в том, что в нем уже есть готовые методы onPreExecute() и onPostExecute(Result) , которые выполняются в основном UI потоке и которые служат для отображение чего-либо и есть метод doInBackground(Params. ) внутри которого и происходит основная работа и он запускается в отдельном потоке автоматически. Вот примерный код как это выглядит:
Все просто и красиво.
Но теперь — немного практики. Вот Вам ошибка от реального пользователя:
А эта ошибка означает, что когда мы вызываем spinner.show() в методе onPreExecute() , то этот ProgressDialog созданный со ссылкой на MyActivity уже неактивен и его нет на экране! Ладно, я еще понимаю как такое может быть при вызове onPostExecute() . Т.е. например пока мы загружали данные пользователь нажал Back и наш ProgressDialog ушел с экрана. Но как такое может быть сразу при вызове загрузки, когда этот код стартует сразу при затуске Activity — это для меня неясно.
Но в любом случае, мы должны обрабатывать такие ситуации поэтому мы решили это обеткой методов spinner.show() и spinner.dismiss() в try/catch . Решение конечно не очень красивое, но в нашем случае — вполне функциональное.
Кстати, такой же код есть и например в Facebook SDK for Android, который был разработан другими опытными разрабочиками. И там тоже у нас были ситуации когда приложение вылетало при закрытии ProgressDialog . Нам пришлось добавить обработку и в их код. Так что проблема эта — не только в нас.
Добавьте сюда еще проблему, что была описана ранее. Что при повороте устройства надо пересоздавать ProgressDialog если поворот был во время загрузки данных. Это тоже добавит сюда вспомогательного кода.
И еще стоит вспомнить что метод doInBackground() выполняется в отдельном потоке и поэтому если при загрузке данных произошла ошибка, то нельзя выдать Alert прямо оттуда, так как это не UI поток. Надо сохранить ошибку, а затем после выхода из потока загрузки в методе onPostExecute(Void result) уже можно что-то показать.
Т.е. опять много вспомогательного кода и не все так просто…
AlarmManager
А еще есть моменты которые вообще не описаны в документации. Например, мы в своем приложении используем AlarmManager (http://developer.android.com/reference/android/app/AlarmManager.html) который помогает нам выдавать сообщения пользователю через некоторое время когда само наше приложение уже закрыто.
Этот AlarmManager — штука очень полезная, вот только проблема в том, что иногда он “теряет” созданные в нем нотификации! Мы потратили кучу времени чтобы понять как и почему это происходит, перерыли всю документацию и ничего не нашли. Совершенно случайно мы “набрели” на это обсуждение — http://stackoverflow.com/questions/9101818/how-to-create-a-persistent-alarmmanager.
Оказывается, что если приложение падает, или пользователь сам убивает приложение через task manager (что возможно и совершенно обычно), то ВСЕ нотификации для этого приложения в AlarmManager УДАЛЯЮТСЯ! Вот это — сюрприз! Особенно, мне понравился там один из комментариев: “Re Alarm canceled: Thanks for the clarification. I asked this on the Android team office hours g+ hangout and they even seemed confused about this behavior. Is it documented anywhere?”
Так что теперь при старте приложения мы вынуждены пересоздавать настроенные нотификации, так как даже нет API в AlarmManager чтобы проверить есть ли такие нотификации или нет.
Бывает и такое.
Вот вам еще несколько ошибок которые мы зарегистрировали у наших пользователей. В своем приложении мы используем OAuth идентификацию для различных социальных сетей и поэтому вынуждены запускать штатный браузер в Android (через который и должен работать OAuth). При этом, он периодически “падает”
Заключение
Несмотря на все вешеописанное, мне понравилась заниматься разработкой под Android. В основном API вполне продуманный и удобный.
Вот только везде стоит использовать try/catch . Даже там, где это совсем неочевидно.
Источник