Android - рекомендации JNI - PullRequest
       24

Android - рекомендации JNI

3 голосов
/ 09 октября 2009

Я хочу включить небольшой, скудный и средний C-парсер в мой проект Android. В прошлом я занимался программированием на JNI, но не разрабатывал нативную (C) разработку для Android. Мой план состоит в том, чтобы скомпилировать C lib в SO и создать оболочку JNI вокруг нее, которую я собираюсь использовать в своем приложении. Это как / можно сделать? Второй и самый важный вопрос - как я могу включить .so в мой APK? Куда это пойдет?

Ответы [ 4 ]

5 голосов
/ 29 января 2010

В зависимости от того, сколько данных вы передаете и как часто я серьезно сомневаюсь, Java / JNI / C будет работать быстрее, чем собственная реализация Java.

Передача чего-либо, кроме "Java Int", в "C long" вызывает процедуры преобразования данных JNI, которые не являются ни худыми, ни средними.

Так что, если ваша подпрограмма JNI не соответствует шаблону:

  • Передайте небольшое количество данных.
  • Много и много работы в C.
  • Передать небольшой результат обратно.

Вы будете значительно медленнее, чем собственная реализация Java. Если вы придерживаетесь базовых «C», таких как Java-операции (+, -, *, ==,>), используя «родные» типы данных (int, char, String) и избегаете фантастических библиотек, Java будет работать почти так же быстро, как C.

Оставшаяся проблема с производительностью Java - это время, затрачиваемое на запуск JVM и начало работы, но когда вы начинаете работать с Java-программой, это не проблема.

Другая причина «медленной» производительности java - люди настаивают на ненужных фабриках, контейнерах, XML-компонентах и ​​т. Д., Где простые и простые методы будут работать лучше.

3 голосов
/ 25 апреля 2012

Создайте папку JNI в корневой папке приложения Android (там, где есть src, res). Поместите код (1), назовите его как someshared-lib.c.

(1)

Java_YourPackageName_YourClassNameWhereYoudeclareYourNativeFunction_NativeFuntionName(JNIEnv* env,jobject thiz)
{


//your c code , the JNI will act as a wrapper for it

return (*env)->NewStringUTF(env, "<string to pass or you can mention jchar * type string >");

}

(2) В файле Java

package YourPackageName;

public class YourClassNameWhereYoudeclareYourNativeFunction extends Activity
{

    public native String  NativeFuntionName();
    String returnValue = NativeFuntionName();


}

(3) В Android.mk сделайте следующее:

LOCAL_PATH: = $ (позвоните в мою директорию)

включает $ (CLEAR_VARS)

LOCAL_MODULE: = someshared-lib // обратите внимание на имя lib, совпадающее с именем файла c

LOCAL_SRC_FILES: = someshared-lib.c // это файл, в который вы поместили код (1)

включает $ (BUILD_SHARED_LIBRARY)

экспорт вашей ndk-сборки (сделать экспорт PATH =: $ PATH

перейдите в папку JNI, как создано выше: выполнить команду ndk-build

вы получите библиотеку, сформированную someshared-lib в папке lib, сформированной в корневой папке Application. будет установлен в устройстве. Чтобы проверить это, вы можете перейти на

/ data / data / your_package_name / lib.

Приложение ищет эту библиотеку в папке / data / data / your_package_name / lib (также / system / lib) и использует ее для динамических вызовов (JNI), выполняемых из приложения Android.

Теперь, если вы хотите вернуть что-то кроме строки, вы должны изменить указанную выше методику в файле c, как показано ниже:

Java_YourPackageName_YourClassNameWhereYoudeclareYourNativeFunction_NativeFuntionName(JNIEnv* env,jclass obj,jobject thiz)
{
jfieldID fid;
jboolean enable_flag;

//Pass the class object having all the variable from the android app to  the JNI in the jclass obj and access its members using the field ID and using Get and Set firld ID.

clazz = (*env)->GetObjectClass(env, info);
fid = (*env)->GetFieldID(env,clazz,"some_variable","X"); //"X" - type of variable for boolean it //is Z , for INtezer it is I, for double it is D,

см. Этот документ для подробного объяснения

//for getting teh value fomr the JNI
 enable_flag = (*env)->GetBooleanField(env, **thiz**, fid);


//for setting the value 

fid = (*env)->GetFieldID(env,clazz,"other_float_variable","D");
(*env)->SetDoubleField(env,**thiz**,fid,other_float_variable);



}

Также в приложении Android вы должны передать объект Class структуры. например,

(2) станет теперь:

пакет YourPackageName;

public class YourClassNameWhereYoudeclareYourNativeFunction extends Activity
{

    public native String  NativeFuntionName();
    String returnValue = NativeFuntionName( exampleStruct exst);

где exampleStruct:

открытый класс exampleStruct {

protected boolean  some_variable = 0;//no log saving by default 
protected float  other_float_variable   = 0;

}

}

Надеюсь, это поможет.

2 голосов
/ 29 января 2010

Кто-то сказал, что JNI в андроиде отстой: http://www.koushikdutta.com/2009/01/jni-in-android-and-foreword-of-why-jni.html

2 голосов
/ 09 октября 2009

использование Android NDK
Скачать n документов Android NDK 1.6

Это избавит вас от написания слоя JNI для lib, а также установит приложение в папку lib вашей папки данных приложения.

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