Кейс | Хранение и запуск устройств (образов) Memu

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
Всем привет, с вами Дмитрий!

В этой статье я расскажу про свое решение, как хранить и запускать образы Memu, при этом не забивать "Диспетчер устройств Memu" большим количеством устройств.

К статье будут прикреплены шаблоны:
  • DCreator - шаблон по созданию Memu устройств;
  • Tester - шаблон для проверки запуска и сохранения устройств Memu;
* Шаблоны Lite - на кубиках, с минимальным C#. Без Lite - полностью на C#.

Немного о работе Memu.
Что такое устройство Memu? Это образ виртуальной машины, предназначенный для имитации ОС Android на ПК. Все устройства хранятся в одной общей папке, из которой осуществляется запуск устройств. Для каждого устройства создается отдельная папка, где хранятся все нужные данные (в том числе и образ устройства), чтобы запустить эмуляцию устройства Android. Если нам для работы нужно большое количество устройств и все они будут лежать в папке для запуска Memu, то у нас возникнут проблемы с их работой. Поэтому, чтобы все запускалось без ошибок, нам нужно хранить образы устройств отдельно и очищать устройства Memu.

Чтобы запустить нужный нам образ, нам достаточно его сохранить\перенести в отдельное хранилище, а потом создать новое устройство, удалить пустой образ, подставить нужный нам образ и новое устройство будет запущено под нужным нам образом со всеми его данными.

Логика работы.
Чтобы мы могли работать с большим количеством устройств, нам нужно:
  1. Создать устройство Memu, запустить его, настроить для работы.
  2. Перенести образ устройства в хранилище.
  3. Удалить устройство из "Менеджера устройств Memu".
Теперь мы получаем хранилище образов нужных нам для работы устройств.

Чтобы запустить нужный нам образ для работы, нам нужно:
  1. Создать новое устройство Memu.
  2. Удалить пустой образ этого устройства.
  3. Перенести нужный нам образ в данное устройство.
  4. Запустить устройство, начать работать.
  5. По завершению работы перенести образ устройства в хранилище.
  6. Удалить устройство из "Менеджера устройств Memu".
Тем самым мы не забиваем "Менеджера устройств Memu" большим количеством устройств и всегда можем запустить из хранилища нужный нам образ и продолжить работать, сохраняя все данные образа.

Вспомогательный Класс MemuVmdk.
Для того, что бы осуществить данную логику, я написал свой класс MemuVmdk, чтобы удобно управлять образами Memu.

Данный класс позволяет переносить образы Memu из папки устройства в папку хранения образов и наоборот, а так же сохранять и подгружать профили устройства ZennoDroid. Класс MemuVmdk находится в общем коде.

Инициализация класса.
Чтобы создать объект MemuVmdk, нужно передать 2 важных параметра:
- mainLaunchMemu - путь к папке, откуда запускаются образы Memu. Где взять данный путь, смотрите ниже на скриншоте.
- mainStorage - путь к папке хранилища образов.
Данные пути мы передаем через Входные настройки.
Код инициализации:
C#:
var mainLaunchMemu = project.Variables["MainLaunchMemu"].Value;
var mainStorage = project.ExecuteMacro(project.Variables["MainStorage"].Value);

var memu = new MemuVmdk(mainLaunchMemu, mainStorage);
После создания объекта MemuVmdk нам будут доступны методы:
  • bool VmdkSave(string launchFolder, string storageFolder)
  • bool VmdkLoad(string launchFolder, string storageFolder)
Эти методы отвечают за сохранение и загрузку образов Memu. В данные методы мы передаем 2 параметра:
- launchFolder: имя папки устройства Memu, которая хранится в общей папке, откуда запускаются все образы Memu. Её мы получаем когда устройство создано и выбрано в ZDP, через методы ZD instance.DroidInstance.Info.Name;
- storageFolder: Если мы сохраняем образ, то генерируем сами, как нам удобно (я беру логин из профиля project.Profile.Login и добавляю информацию для удобного понимания, например ZD_Версия Андройд). Если мы загружаем образ, то получаю имя нужной нам папки из хранилища образов.
Данные методы являются логическими, то есть возвращают:
True - если все было выполнено без ошибок;
False - если не удалось перенести файлы.

Примеры:
C#:
var v = project.Variables["android_V"].Value;

var launchFolder = droid.Info.Name;
var storageFolder = $"ZD_{v} {profile.Login}";
var isMove = memu.VmdkSave(launchFolder, storageFolder);
if (!isMove)
{
    throw new Exception("Ошибка переноса рабочего образа");
}
project.SendInfoToLog("Перенесли образ", true);

C#:
// Создаем устройство Memu
var mainLaunchMemu = project.Variables["MainLaunchMemu"].Value;
var mainStorage = project.ExecuteMacro(project.Variables["MainStorage"].Value);

var storageFolder = project.Variables["StorageFolder"].Value;

var droid = instance.DroidInstance as IDroidInstanceEmulatorAPI;
var memu = new MemuVmdk(mainLaunchMemu, mainStorage);
var v = memu.ProfileLoad(project.Profile, storageFolder);

var name = "Work_" + project.Profile.Login;
droid.Action.Create(v);
droid.Action.Rename(droid.Info.Index, name);

var launchFolder = droid.Info.Name;

// Удаляем пустой образ.
var isDelet = memu.DeletVmdk(launchFolder);
if (!isDelet)
{
    throw new Exception("Ошибка удаления пустого образа");
}
project.SendInfoToLog("Удалили пустой образ", true);

// Подгружаем образ и запускаем
var isMove = memu.VmdkLoad(launchFolder, storageFolder);
if (!isMove)
{
    throw new Exception("Ошибка переноса рабочего образа");
}
project.SendInfoToLog("Подгрузили рабочий образ", true);
  • bool DeletVmdk(string launchFolder)
Метод удаления образа из папки устройства. Он нужен, чтобы удалить пустой образ, когда мы хотим запустить свой образ. Так же является логическим, если пустой образ удалили вернет True, если возникли проблемы, вернет False.


C#:
var launchFolder = droid.Info.Name;

// Удаляем пустой образ.
var isDelet = memu.DeletVmdk(launchFolder);
if (!isDelet)
{
    throw new Exception("Ошибка удаления пустого образа");
}
project.SendInfoToLog("Удалили пустой образ", true);
  • void ProfileSave(IProfile profile, string storageFolder, string version)
Метод для сохранения профиля ZennoDroid. Нужен, чтобы сохранить данные устройства с которым работает наш образ. Принимает 3 параметра:
- IProfile profile: передаем project.Profile
- storageFolder: имя папки, куда мы сохраняем данные
- version: версия Android, с которым мы работаем, в дальнейшем по этому имени будет создаваться устройство. Имя берется из входных настроек версии Android.


C#:
var v = project.Variables["android_V"].Value;
var profile = project.Profile;
var storageFolder = $"ZD_{v} {profile.Login}";

memu.ProfileSave(profile, storageFolder, v);
project.SendInfoToLog("Профиль сохранен", true);
  • string ProfileLoad(IProfile profile, string storageFolder)
Метод загрузки профиля для работы устройства. Важно! данный метод возвращает версию Android устройства, которую нужно будет создать, чтобы подгрузить наш образ.
Принимает:
- IProfile profile: передаем project.Profile
- storageFolder: имя папки, куда мы сохраняем данные


C#:
var storageFolder = project.Variables["StorageFolder"].Value;

// Подгружаем профиль
var v = memu.ProfileLoad(project.Profile, storageFolder);
// Создаем устройство
var name = "Work_" + project.Profile.Login;
droid.Action.Create(v);
droid.Action.Rename(droid.Info.Index, name);

Запускаем шаблон DCreator
ВАЖНО! Заходим во входные настройки и указываем Директория запуска устройств Memu и Директория хранения устройств.

Директория хранения устройств - указываете папку, где будут храниться образы устройств.

Директорию запуска устройств Memu - берем из "Диспетчера устройств Memu"

124690


124691

Там хранятся данные всех наших эмуляторов Memu.

Выбираем устройство, которое хотим создать. Если нужно установить приложения - указываем путь к папке, где хранятся apk.
Запускаем шаблон, можем запустить диспетчер устройств Memu, чтобы посмотреть, как это работает.
Все готово, устройство создано, образ перенесен в хранилище, устройство удалено из Memu.

Проверка работы образов.
Запускаем шаблон Tester, во входных настройках указываем Директория запуска устройств Memu и Директорию хранения устройств, как в DCreator, и имя папки устройства, которое хотим запустить.
124948


Шаблон Tester создаст новое устройство Memu, очистит пустой образ, подгрузит нужный образ, запустит эмулятор. После работы вернет образ в хранилище и удалит устройство из Memu.

(Tester) Данный шаблон - это пример работы с образами.
Для ваших проектов нужно будет делать менеджер образов через Базу Данных или XML файл с хранением данных о занятости образа.


Важно: Android 12 пока не работает как нужно, это проблема на стороне Memu, а не ZDP. Проблема заключается в том, что если перенести образ Android 12, он больше не запустится.



#####################
Мой Телеграм Канал
Мой Youtube Канал

Поддержка автора: Донат
USDT TRC20: TBbnjJGwHEeKP5KEr7FNhsBmhR6V1XKds1
#####################

У кого проблемы с YouTube, продублировал видео в ВК
 

Вложения

Последнее редактирование:

seodamage

Client
Регистрация
08.09.2014
Сообщения
224
Благодарностей
67
Баллы
28
привет, а со символьной ссылкой не пробовал? чтобы туда сюда образы не гонять
 
  • Спасибо
Реакции: Dmitriy Ka

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
733
Благодарностей
485
Баллы
63
привет, а со символьной ссылкой не пробовал? чтобы туда сюда образы не гонять
Я хотел такое сделать, но не знал как это называется :-)
Когда реализовал через File.Move, скорость переноса устраивала, поэтому продолжил работать через него.

Для себя и для всех сделаю такую пометку:

Метод File.Move в C# выполняет перемещение файлов быстро, потому что, когда вы перемещаете файл в пределах одного диска или раздела, не происходит физического копирования данных. Вместо этого система обновляет метаданные файловой системы, такие как путь к файлу, и это происходит очень быстро.

Причины быстрой работы File.Move:
  1. Нет физического копирования данных: Если файл перемещается внутри одного диска или раздела, система не перемещает его данные, а только обновляет информацию о местоположении файла. Это не требует много времени, так как сами данные на диске остаются на том же месте.
  2. Обновление метаданных: Операционная система меняет только путь к файлу в таблице файловой системы. Эта операция не затрагивает фактические данные, а только ссылки на них, что делает процесс очень быстрым.
  3. Оптимизация файловой системы: Файловые системы, такие как NTFS или ext4, поддерживают операции перемещения, которые сводятся к простому изменению указателей на файл в структуре каталогов.
Когда File.Move работает медленнее:
  • Если вы перемещаете файл на другой диск или раздел, то данные должны быть физически скопированы с одного места на другое, что требует времени в зависимости от размера файла и скорости передачи данных.
  • При перемещении файла по сети данные передаются через сеть, что также занимает больше времени.
Пример:
Перемещение файла в пределах одного раздела:
  • Исходный файл остается на месте.
  • Изменяется только информация о том, где файл находится в структуре директорий.
Перемещение файла на другой диск:
  • Происходит физическое копирование данных на новый диск, что может занять больше времени.
 
  • Спасибо
Реакции: seodamage

Lest

Client
Регистрация
20.03.2020
Сообщения
68
Благодарностей
72
Баллы
18
Хотелось бы разбор всех возможных способов хранение. Так как хранение всего образа, по моему самый плохой не масштабируемый способ. Оно занимает очень много места. Чтобы его экономить, лучше сохранять только данные приложения, а если это браузер, то вообще несколько папок, и вместо нескольких гигов - будет весить несколько сотен килобайт. Потом создаёшь новое устройство с теме же параметрами и перекидываешь обратно эти папки. Хотя для разных целей, разные способы предпочтительнее.
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)