2013-12-13 4 views
2

JNI_OnLoad에 인쇄 로그 문을 추가했지만 호출되지 않았습니다. JNI_OnLoad 메서드가 있습니다. System.loadLibrary를 호출 할 때 onJNILoad가 호출되지 않음

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { 
    __android_log_print(ANDROID_LOG_INFO, __FUNCTION__, "onLoad"); 
    // some init code 
} 

내가 특정 파일에주는 JNI_OnLoad을 선언하거나 Android.MK이 어디주는 JNI_OnLoad 방법을 찾을 수있는 시스템을 말한다에 STH를 선언해야합니까? 이제 많은 .cpp 파일 중 하나에 넣었습니다.

컴파일 된 .so lib가 첨부됩니다. so 파일을 덤프하려고하면 JNI_OnLoad 메서드를 내 보낸 것으로 확신합니다. https://docs.google.com/file/d/0B089WeEZXTb3ZjZiQllaYThuUUk/edit

사실 저는 안드로이드 소스 (libcorejava.so)에서 라이브러리를 이식하려고합니다. 클래스 경로 충돌을 피하기 위해 클래스 경로를 이미 변경했습니다. 여기

그리고

이주는 JNI_OnLoad를 선언하는 파일입니다 : 이미 표준 서명과 일치하기 위해 위의 하나에 서명을 변경 https://android.googlesource.com/platform/libcore/+/master/luni/src/main/native/Register.cpp

편집 : 안드로이드 소스를로드하지 않는 것으로 확인 System.loadLibrary에 의해! 그것은 libcorejava가 System.loadLibrary를 구현하는 데 사용되므로 System.loadLibrary를 사용하여로드 할 수 없다고 말합니다. 그러나 필자의 경우에는 기능의 일부만 필요하기 때문에 (ICU 관련) 문제가되어서는 안됩니다.

https://android.googlesource.com/platform/dalvik/+/master/vm/Init.cpp

// Most JNI libraries can just use System.loadLibrary, but you can't 
    // if you're the library that implements System.loadLibrary! 
    loadJniLibrary("javacore"); 
    loadJniLibrary("nativehelper"); 

편집 2 :
그것은 것으로 밝혀 라이브러리의 이름 충돌 때문에! 하지만 libjavacore에는 다른 라이브러리가 필요합니다. 내가 잃어버린 의존성을 나열 할 수있는 도구가 있습니까?

java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1286]: XXX 

편집 3 :
TextClock 시간을 표시하기위한 새로운 API입니다. 4.2 이상에서만 존재합니다. 이전 DSK에서 사용할 수 있도록 백 포트하려고합니다. libjavacore에있는 ICU 라이브러리에 따라 다릅니다. 그래서 Android.mk 파일을 수정하여 libjavacore에 icu 관련 소스 파일 만 포함되도록하고 마지막 컴파일은 파일이 내 apk에 포함되도록합니다.

TextClock :
http://developer.android.com/reference/android/widget/TextClock.html

그것은 지금 원래 TextClock을 지원하는 휴대폰에서 작동하지만 오래된 장치에서 작동하지 않습니다. 다음은 예외 로그입니다. 나는 libjavacore가 ICU 라이브러리의 래퍼이기 때문에 그것이라고 생각한다. 래퍼 외에도 ICU 라이브러리를 포팅해야합니다. ICU 라이브러리의 크기가 매우 크고 보인다 그것에 대한 가치가하지 않는하지만

12-13 14:07:54.859: E/AndroidRuntime(2091): java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1306]: 36 cannot locate '_ZN6icu_516Locale14createFromNameEPKc'... 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at java.lang.Runtime.loadLibrary(Runtime.java:370) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at java.lang.System.loadLibrary(System.java:535) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at com.example.time.MainActivity.onCreate(MainActivity.java:20) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.Activity.performCreate(Activity.java:5008) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.ActivityThread.access$600(ActivityThread.java:130) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.os.Looper.loop(Looper.java:137) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at android.app.ActivityThread.main(ActivityThread.java:4745) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at java.lang.reflect.Method.invokeNative(Native Method) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at java.lang.reflect.Method.invoke(Method.java:511) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    12-13 14:07:54.859: E/AndroidRuntime(2091):  at dalvik.system.NativeStart.main(Native Method) 
+0

많은 cpp 파일 중 하나에 넣어도 괜찮습니다. 나는 그 문제가 뭔지 모르지만 이것이 원인이 아니라고 확신한다. 내 마음에 오는 것은 함수 앞에 extern "C"를 넣는 것을 잊었다는 것입니다. – eozgonul

+0

YS havent. 왜 그것을 필요로합니까? – Bear

+0

http://stackoverflow.com/a/1041880/2359247 – eozgonul

답변

1

당신은 당신의 툴체인 폴더에 readelf를 사용하여 .so를 파일에 기호를 덤프 할 수 ... 포기 하겠어 . JNI_OnLoad가 내보내 졌는지 확인하십시오. -s (symbols) 명령과 libs 폴더의 .so 파일 이름이이를 수행해야합니다.

1

이전 버전의 Android의 경우 라이브러리는 libjavacore.a과 연결된 libnativehelper.so과 연결된 VM (libdvm.so)과 직접 연결되었습니다. 최근 릴리스 this changed에서는 내부 네이티브 라이브러리로드 메커니즘을 사용하여 항상 시작시 라이브러리를로드하므로 JNI_OnLoad이 있으면 호출됩니다.

내가 실행하면 adb shell dalvikvm Foo ("푸"가 존재하지 않는 경우), 내가 로그 캣에서 볼 :

D dalvikvm: Trying to load lib libjavacore.so 0x0 
D dalvikvm: Added shared lib libjavacore.so 0x0 
D dalvikvm: Trying to load lib libnativehelper.so 0x0 
D dalvikvm: Added shared lib libnativehelper.so 0x0 
D dalvikvm: No JNI_OnLoad found in libnativehelper.so 0x0, skipping init 

는 그래서 libjavacore.so로드 분명히 발견하고 (아무 소식이 좋은 소식 없음) JNI_OnLoad 달렸다. libnativehelper.so을로드 했으므로 JNI_OnLoad을 찾지 못했습니다. 그렇지 않으면 예상했던 경우를 대비하여 메시지가 기록됩니다. 당신이 (뿌리 장치) /system/lib에서 libjavacore.so을 대체하고 dalvikvm 명령을 실행하면 내가 위에 표시된 것 같은

, 당신은 메시지와 함께 혼합 로그 파일에 메시지를 볼 수 있습니다. 시스템을 다시 시작하면 zygote 시작시 메시지가 표시되고 Dalvik 기반 명령 (예 : am)이 실행되지 않으면 메시지가 표시됩니다.

+0

예 ... 바꾸거나 라이브러리 경로를 exec *() 함수를 호출하기 전에 원래 *를 재정의하면 처음부터 초기화됩니다. 그러나 나는 포스터가 자신의 .apk에 자신의 패키지를 포장하고 명시 적으로로드하려고 시도하고 있다고 생각합니다. 시스템 버전이 이미 부모 Zygote에로드되어 있기 때문에 하위 APK 프로세스에로드하려고 시도하기 전에 작동하지 않을 수도 있습니다. –

+0

아. VM이 동일한 lib라고 생각하면 logcat에 "이미로드 된"메시지가 있어야합니다. 그렇지 않으면,'JNI_OnLoad'가 그냥 작동하도록 (그리고 명시 적 등록을 사용하기 때문에 old를 대체하는 새로운 방법) 기대할 것입니다.이전에 공유 라이브러리의 이름을 바꿀 것을 제안하면 문제가 해결 될 것입니다. – fadden

+1

@fadden 죄송합니다. 교체하는 대신 라이브러리를 이식 ​​할 예정입니다. 그래서 이름 바꾸기가 작동합니다. 모두들 고마워. – Bear

관련 문제