#path #add #aapt
#путь #Добавить #aapt
Вопрос:
Я использую инструмент aapt для удаления некоторых файлов из разных папок моего apk. Это работает нормально.
Но когда я хочу добавить файлы в apk, команда aapt tool add не позволяет мне указать путь, по которому я хочу добавить файл, поэтому я могу добавлять файлы только в корневую папку apk. Это странно, потому что я не думаю, что разработчики никогда не захотели бы добавлять файлы во вложенную папку apk (например, папку res). Возможно ли это с помощью aapt или любого другого метода? Причина удаления файлов из любой папки работает нормально, а добавление файла работает только для корневой папки apk. Не могу использовать это для любой другой папки.
Спасибо
Ответ №1:
Инструмент aapt сохраняет структуру каталогов, указанную в команде add, если вы хотите добавить что-либо в существующую папку в apk, у вас просто должна быть похожая папка в вашей системе, и вы должны указать каждый файл, чтобы добавить полный список каталогов. Пример
$ aapt list test.apk
res/drawable-hdpi/pic1.png
res/drawable-hdpi/pic2.png
AndroidManifest.xml
$ aapt remove test.apk res/drawable-hdpi/pic1.png
$ aapt add test.apk res/drawable-hdpi/pic1.png
Добавляемый файл pic1.png находится в папке в текущем рабочем каталоге терминала res / drawable-hdpi / , надеюсь, это ответило на ваш вопрос
Комментарии:
1. Я уже написал свой собственный инструмент для замены aapt на то, что мне было нужно. Но спасибо за идею. Полезно знать на будущее. Я бы проголосовал за ваш ответ, но у меня пока нет необходимой репутации.
Ответ №2:
На самом деле в aapt
есть ошибка, которая сделает это случайным образом невозможным. Предполагается, что это должно работать так, как утверждается в другом ответе: пути сохраняются, если вы не передадите -k
. Давайте посмотрим, как это реализовано:
Флаг, который определяет, игнорируется ли путь, является mJunkPath
:
bool mJunkPath;
Эта переменная находится в классе с именем Bundle
и управляется двумя средствами доступа:
bool getJunkPath(void) const { return mJunkPath; }
void setJunkPath(bool val) { mJunkPath = val; }
Если пользователь указал -k
в командной строке, для него установлено значение true
:
case 'k':
bundle.setJunkPath(true);
break;
И, когда данные добавляются в файл, он проверяется:
if (bundle->getJunkPath()) {
String8 storageName = String8(fileName).getPathLeaf();
printf(" '%s' as '%s'...n", fileName, storageName.string());
result = zip->add(fileName, storageName.string(),
bundle->getCompressionMethod(), NULL);
} else {
printf(" '%s'...n", fileName);
result = zip->add(fileName, bundle->getCompressionMethod(), NULL);
}
К сожалению, один экземпляр, Bundle
используемый приложением, выделен в main
стеке, и в конструкторе нет инициализации mJunkPath
, поэтому значение переменной является случайным; без способа явно установить его на false
, в моей системе я (по-видимому, детерминированно) не могу добавлять файлы по указанным путям.
Однако вы также можете просто использовать zip
, поскольку APK — это просто Zip-файл, и zip
инструмент работает нормально.
(Для справки, я еще не отправил тривиальное исправление для этого в виде патча для Android, если кто-то еще захочет, мир, вероятно, станет лучше. Мой опыт работы с процессом отправки кода Android заключался в том, что мне приходилось мириться с невероятно сложным механизмом отправки, который в итоге занял шесть месяцев, прежде чем кто-то перезвонил мне, в некоторых случаях с незначительными изменениями, которые могли быть просто внесены с их стороны, если бы процесс отправки не был таким ужасно сложным. Учитывая, что существует действительно простое решение этой проблемы, я не считаю это достаточно важным, чтобы снова беспокоиться обо всем этом.)
Комментарии:
1. спасибо за информацию, Джей. Я, наконец, написал простой инструмент Java, который добавляет файл в apk (считая его [как вы сказали] zip), используя ZipInputStream и ZipEntry.
2. Я предполагаю, что под «zip tool» вы имеете в виду какой-либо инструмент с именем «zip», а не тип архива, потому что разархивировать apk и добавить некоторые файлы довольно просто, но сжать его обратно, а также создать вновь добавленные файлы, что невозможно с «zip» 😉 Для этого я использовал apktool.
3. Я не понимаю, что вы подразумеваете под «созданием вновь добавленных файлов»; в моем случае я добавляю такие вещи, как
classes.dex
(созданные с помощьюdx
), в существующий APK с помощьюzip my.apk classes.dex
без проблем.4. Например, если я захочу изменить значок моего приложения, просто заменив изображение значка в папке res / drawable, это не сработает. Я предполагаю, что новому ресурсу нужен идентификатор в автоматически сгенерированном классе R, который генерируется при сборке. Итак, я использовал apktool для декодирования apk, затем добавил свое новое изображение, а затем снова собрал apk, снова используя apktool.
5. Привет, Джей, у меня к тебе вопрос. Мне нужно удалить «classes.dex» из существующих файлов .apk в папке data / app. Затем мне нужно переупаковать его как обычный .apk. Я должен сделать это с помощью zipfile на java. Но что происходит, когда я запускаю его в эмуляторе, вместо исходного значка появляется какой-то фиктивный значок. Но переустановите папку и manifest.xml там есть все. Можете ли вы ввести некоторые входные данные??