#java-native-interface #native
Вопрос:
В Android Studio MainActivity
я пишу что-то вроде
int itemA_num = 0;
int itemB_num = 0;
ABCListener mabclistener = new ABCListenter() {
@Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num ;
}
}
ABCobject mabcobject = (ABCobject) findviewById(R.id.abcobject1);
mabcobject.setListener(mabcListener);
Я не хочу, чтобы люди декомпилировали мой APK и изменяли код, изменяя значение или добавляя что-то подобное:
ABCListener mabclistener = new ABCListenter() {
@Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num = 10000; //possibly some general name read by those guys and modified as int1 =10000;
itemB_num = 500; //possibly some general name read by those guys and added this line int2 =500;
}
}
Поэтому я хочу использовать JNI с Cmake. Внутри файла .cpp я хочу создать объект класса findviewById
, setListener
и создать ABCListener
.
Я знаю, используя формат
jclass cls = (jclass) env->FindClass("abc/def/GHI");
jmethodID mid = (jmethod) env->GetMethodID(cls, "methodname", "(xxxx)yyy");
jobject obj = (jobject) env->CallObjectMethod(cls, mid, params);
Однако, если я хочу написать код ABCListener
и использовать jobject
его, я не знаю, как и где сообщить машине, что я собираюсь написать некоторый код, относящийся к @Override public void onEventActivated(CustomResult result) { ... }
ней . Я также хочу добавить несколько строк кода внутри ответа в JNI.
Я нашел веб-сайт, «похожий» на этот вопрос, но он с 2011 года и примерно доступен для запуска. https://community.oracle.com/tech/developers/discussion/2298550/overriding-interface-methods-via-jni Я не знаю, будет ли это по-прежнему работать в 2021 году.
Комментарии:
1. Если ваша модель угроз уже предполагает, что люди будут изменять ваш код, что помешает им снова заменить вашу собственную реализацию на Java?
Ответ №1:
Во-первых, определите новый класс на стороне Java:
class NativeABCListener implements ABCListener {
@Override public native void onEventActivated(CustomResult result);
}
Затем создайте экземпляр NativeABCListener
либо на Java, либо в машинном коде и прикрепите его к своему mabcobject
. Вы знаете, как это сделать, поэтому я не буду это повторять.
На родной стороне вы просто определяете метод C с соответствующим именем:
JNIEXPORT void JNICALL Java_your_package_NativeABCListener_onEventActivated(JNIEnv *env, jobject thiz, jobject result) {
...
}
Если вам нужно несколько ABCListeners
классов, которые выполняют разные действия, вы можете создать несколько NativeABCListener
классов (каждый со своей собственной соответствующей собственной функцией) или изменить NativeABCListener
, чтобы сохранить указатель функции C в long
поле Java. В ..._onEventActivated
функции вы затем извлекаете поле thiz
и вызываете его как обычный указатель functino.