Хостинг исполняемого файла в приложении Android

Я работаю над Android-приложением, которое зависит от двоичного файла ELF: наш код Java взаимодействует с этим двоичным кодом, чтобы все было сделано. Эта среда исполнения должна быть запущена и завершена при запуске приложения и выходе приложения / по требованию.

Вопросов:

  1. Я предполагаю, что мы сможем выполнить этот двоичный файл с помощью API Runtime.exec (). Есть ли какие-либо ограничения относительно того, где мне нужно помещать мою библиотеку в структуру папок? Как бы среда выполнения системы находила этот исполняемый файл? Есть ли какие-то настройки classа?

  2. Поскольку приложение имеет зависимости от этого времени выполнения, я думал об обертке вокруг службы, чтобы ее можно было запустить или остановить по мере необходимости. Каков наилучший способ обработки таких исполняемых файлов в проекте Android?

  3. Каковы другие альтернативы, предполагая, что у меня нет исходного кода для этого исполняемого файла?

Пожалуйста посоветуй.

Благодарю.

1) Нет, не должно быть ограничений, кроме тех, которые получают доступ к системным файлам и, следовательно, требуют root. Лучшее место было бы прямо в / data / data / [your_package_name], чтобы избежать загрязнения в другом месте.

2) Очень подробное обсуждение компиляции в отношении родных библиотек можно найти здесь: http://www.aton.com/android-native-libraries-for-java-applications/ . Другой вариант – кросс-компилятор для руки (вот тот, который использовался для компиляции ядра, он бесплатный: http://www.codesourcery.com/sgpp/lite/arm ). Если вы планируете поддерживать службу, которая выполняет ваш cammand, будьте предупреждены о том, что службы могут быть остановлены и перезагружены андроидом в любой момент.

3) Теперь, если у вас нет исходного кода, я надеюсь, что ваш файл, по крайней мере, скомпилирован как исполняемый файл. Если нет, я не понимаю, как вы могли его запустить.


Вы выполните файл, выполнив следующие команды в своем classе java:

String myExec = "/data/data/APPNAME/FILENAME"; Process process = Runtime.getRuntime().exec(myExec); DataOutputStream os = new DataOutputStream(process.getOutputStream()); DataInputStream osRes = new DataInputStream(process.getInputStream()); 

Я ничего не знаю о вашем исполняемом файле, так что вам может понадобиться или не понадобиться на самом деле получить inputStream и outputStream.


Я предполагаю, что запуск adb для толкания двоичного файла не может быть и речи, поэтому я искал опрятный способ его упаковки. Я нашел отличный пост о включении исполняемого файла в ваше приложение. Проверьте это здесь: http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App

Важная часть – это одна (акцент мой):

Из приложения Android Java, используя папку с assets

  • Включите двоичный файл в папке с ресурсами.
  • Используйте getAssets().open(FILENAME) чтобы получить InputStream .
  • Запишите его в /data/data/APPNAME (например, /data/data/net.gimite.nativeexe ), где ваше приложение имеет доступ к файлам записи и делает его исполняемым.
  • Запустите /system/bin/chmod 744 /data/data/APPNAME/FILENAME используя приведенный выше код.
  • Запустите исполняемый файл, используя приведенный выше код.

Сообщение использует папку с assets , установленную в raw папке, которую предлагает андроид для статических файлов:

Совет. Если вы хотите сохранить статический файл в своем приложении во время компиляции, сохраните файл в каталоге проекта res / raw /. Вы можете открыть его с помощью openRawResource (), передав R.raw. идентификатор ресурса. Этот метод возвращает InputStream, который вы можете использовать для чтения файла (но вы не можете записать его в исходный файл).

Чтобы получить доступ к папке с данными, вы можете выполнить следующие инструкции: http://developer.android.com/guide/topics/data/data-storage.html#filesInternal Кроме того, есть File#setExecutable(boolean); метод, который должен работать вместо команды оболочки.

Итак, поставив все вместе, я бы постарался:

 InputStream ins = context.getResources().openRawResource (R.raw.FILENAME) byte[] buffer = new byte[ins.available()]; ins.read(buffer); ins.close(); FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(buffer); fos.close(); File file = getFileStreamPath (FILENAME); file.setExecutable(true); 

Конечно, все это нужно делать только один раз после установки. Вы можете быстро проверить внутри onCreate() или все, что проверяет наличие файла и выполняет все эти команды, если файл там отсутствует.

Дайте мне знать, если это сработает. Удачи!

Ниже приведено полное руководство по пакету и запуску исполняемого файла. Я основывал его на том, что я нашел здесь, и на других ссылках, а также на моих собственных проб и ошибок.

1.) В проекте SDK поместите исполняемый файл в папку / assets

2.) Программно получить строку этого каталога файлов (/ data / data / your_app_name / files), как это

 String appFileDirectory = getFilesDir().getPath(); String executableFilePath = appFileDirectory + "/executable_file"; 

3.) В Java-коде приложения вашего приложения: скопируйте исполняемый файл из папки / assets в подпапку «файлы» вашего приложения (обычно / data / data / your_app_name / files) с такой функцией:

 private void copyAssets(String filename) { AssetManager assetManager = getAssets(); InputStream in = null; OutputStream out = null; Log.d(TAG, "Attempting to copy this file: " + filename); // + " to: " + assetCopyDestination); try { in = assetManager.open(filename); Log.d(TAG, "outDir: " + appFileDirectory); File outFile = new File(appFileDirectory, filename); out = new FileOutputStream(outFile); copyFile(in, out); in.close(); in = null; out.flush(); out.close(); out = null; } catch(IOException e) { Log.e(TAG, "Failed to copy asset file: " + filename, e); } Log.d(TAG, "Copy success: " + filename); } 

4.) Измените права доступа к файлу на исполняемый_файл, чтобы фактически сделать его исполняемым. Сделайте это с помощью Java-вызовов:

 File execFile = new File(executableFilePath); execFile.setExecutable(true); 

5.) Выполните файл следующим образом:

 Process process = Runtime.getRuntime().exec(executableFilePath); 

Обратите внимание, что любые файлы, на которые ссылаются здесь (например, входные и выходные файлы), должны иметь свой полный путь. Строки построены. Это потому, что это отдельный процесс, и он не имеет понятия о том, что такое «pwd».

Если вы хотите прочитать stdout команды, вы можете это сделать, но до сих пор он работает только для меня для системных команд (например, «ls»), а не для исполняемого файла:

 BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); int read; char[] buffer = new char[4096]; StringBuffer output = new StringBuffer(); while ((read = reader.read(buffer)) > 0) { output.append(buffer, 0, read); } reader.close(); process.waitFor(); 

Log.d (TAG, “output:” + output.toString ());

Я сделал что-то подобное с помощью NDK. Моя страtagsя состояла в том, чтобы перекомпилировать программу с помощью NDK и написать некоторый код JNI-оболочки, который вызывается в main функции программы.

Я не уверен, что такое жизненный цикл кода NDK. Даже услуги, которые предназначены для долговременного использования, могут быть запущены и остановлены системой, когда это удобно. Вам, вероятно, придется отключить stream NDK и при необходимости перезапустить его.

  • получение ошибки компиляции для оператора бриллианта в идее ide
  • Разница между списком и массивом
  • Попытка вызвать виртуальный метод 'android.view.Window $ Callback android.view.Window.getCallback ()' для ссылки на нулевой объект
  • Android Studio не смог найти действительный Jvm (относящийся к MAC OS)
  • Понимание использования Spring @Autowired
  • Предотrotation запутывания имени члена classа ProGuard
  • Разбор строки по дате формата в java defaults датируется 1 и месяц до января
  • Создайте библиотеку Jar для Android для распространения
  • Как проверить тип переменной в Java?
  • Скрытие строк в Obfuscated code
  • Как разбирать массив JSON с помощью Gson
  • Interesting Posts

    Невозможно сжать C: раздел за пределами 297 МБ

    Почему pinging 192.168.072 (всего 2 точки) возвращает ответ от 192.168.0.58?

    Каковы различия между абстрактными classами и интерфейсами в Java 8?

    Почему C ++ не позволяет унаследовать дружбу?

    Можно ли создать проект java только один раз, используя eclipse и поделиться?

    Использование планировщика GWT

    Что я могу сделать, чтобы остановить кнопку Play / Pause от открытия iTunes?

    Заполните отверстия в OpenCV

    Отключение ввода в консоли C # до завершения определенной задачи

    Что такое данные пула DMI и почему он проверен?

    Как заставить сканер отбрасывать исключения при вводе неправильного типа?

    Родные запросы JPA / Hibernate не распознают параметры

    Как изменить поля внутри нового типа данных PostgreSQL JSON?

    Могу ли я безопасно подключить только кабель питания USB-Y к другому источнику питания?

    RecyclerView и java.lang.IndexOutOfBoundsException: обнаружена несогласованность. Недействительный адаптер держателя держателя ViewView в устройствах Samsung

    Давайте будем гением компьютера.