2013-04-22 2 views
3

Android가 아닌 사람들을위한 서문 (일부 Linux 사용자는이 정보로 답을 알고있을 수 있음) :Android에서 동적으로로드 된 라이브러리를 닫는 방법이 있습니까?

Android의 모든 응용 프로그램은 Dalvik 가상 시스템의 인스턴스에서 실행됩니다. 응용 프로그램을 시작할 때 ActivityManager라는 엔티티는 파이프에 기록하여 Zygote라는 다른 엔티티에 응용 프로그램을 시작해야한다고 알립니다. Zygote는 라이브러리가 사전로드 된 빈 슬레이트 Dalvik VM 인스턴스이며 파이프를 통해 소환되면 복제되고 복제본은 실행될 응용 프로그램과 관련된 Linux 사용자의 권한 수준을 낮 춥니 다. 이렇게하면 앱을 시작할 때 시간과 메모리를 절약 할 수 있습니다. 모든 라이브러리를 다시로드하고 매번 모든 설정을 수행 할 수 있습니다.

내 문제는 내 자신의 버전의 라이브러리를 사용하고자하므로이 특정 프로세스에서 닫으려는 Zygote에서로드되는 특정 라이브러리가 있다는 것입니다. 응용 프로그램이 시작될 때 적절한 폴더에 복사되고 Java 레이어 "System.load ('xyz')를 통해로드 된 내 .so 파일과 내 원시 코드를 연결했지만 내 코드가 실행될 때 원래 시스템 라이브러리의 기능이지 내 것이 아닙니다. "cat/proc/NNNN/maps"를 실행하면 오래된 라이브러리가 광산뿐만 아니라 메모리에 있음을 알 수 있습니다.

내 응용 프로그램에서 특정 라이브러리를 닫을 수있는 방법이 있습니까? 그렇지 않다면 그 라이브러리에있는 함수에 대한 모든/모든 호출이 이전 버전 대신 MY 버전으로 전달되도록하는 방법이 있습니까?

감사합니다.

+0

이전에로드 된 공유 라이브러리를 언로드 할 때와 같이 "닫기"하시겠습니까? 방법이없는 것처럼 보입니다. https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/59Xu4kKjgnA 및 https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/를 참조하십시오. sF56xVIySfI – MarsAtomic

+0

@MarsAtomic : 그 게시물은 앱 자체가로드 한 라이브러리를 언로드하는 것과 관련이 있습니다. 이는 약간 다릅니다. 'System.load()'에 의존하는 대신 자신의'dlopen()'/'dlclose()'호출을 관리한다면 실제로 그것을 할 수 있습니다. 모든 것이 앱의 통제하에 있기 때문에 안전하게 할 수 있습니다. 이는 실제로 앱을 재시작하지 않고 공유 라이브러리를 업데이트하려는 경우 (또는 서비스 가능성이 더 높은 경우)에 해당하는 반면 시스템의 라이브러리 복사본을 대체하는 것에 대한 문제입니다. – fadden

+0

안녕하세요! 실제로 저는 Zygote에서 기본적으로로드 된 라이브러리를 언로드하여 (DVM 인스턴스에서) 해당 라이브러리의 다른 버전을 직접로드하고 일반적으로 원본 라이브러리로 이동하는 호출을 대신 실행합니다. – ZachM

답변

2

공유 라이브러리 (dlclose())를 닫는 것은 라이브러리 코드를 매핑 해제하기 때문에 최상의 상황에서 까다로울 수 있습니다. 이후에 뭔가가 해당 코드 (아마도 C++ 소멸자)를 호출하면 프로그램이 즉시 중단됩니다. 라이브러리가 당신의 코드가 아닌 다른 코드에 의해로드 되었기 때문에 맵핑을 해제하는 순간 다른 라이브러리가 해당 라이브러리의 코드를 실행하여 다시 충돌을 일으킬 가능성이 있습니다.

그렇게하지 마십시오. :-)

정적 라이브러리로 라이브러리 버전을 빌드하고 코드에 직접 링크 할 수 있으면 문제를 완전히 피할 수 있어야합니다.

FWIW에서는 다양한 라이브러리 (특히 SSL 및 ICU)가 접합체에 명시 적으로로드되지 않은 Dalvik에 링크되어 있으므로이 중 하나를 바꾸려면 /system/lib 버전을 가져올 수 있습니다. 접합체 또는 아닙니다.

+0

안녕하세요! 감사! 나는 그렇게하지 않을 것에 동의한다. 메모리에서 직접적으로 맵핑을 해제하는 몇 가지 깔끔한 메모리 트릭을 뽑았으나 마침내 dlopen()을 사용하여 직접 열어서 dlsym()을 사용하여 필요한 함수 포인터를 꺼 냈습니다. 이것은 훨씬 더 신뢰할 수 있습니다. – ZachM

+0

또한 올바른지에 대한 메모로 - 작은 라이브러리를 사용하거나 하나의 응용 프로그램에서 사용하는 경우 정적 라이브러리 사용과 관련된 fadden의 대답을 제안합니다. 안드로이드의 사용자 정의 빌드를위한 응용 프로그램 모음을 작성하고 있으므로 20 개의 다른 것들에 정적으로 링크하면 낭비가 될 수 있으므로 dlopen()/dlsym()/dlclose()를 사용하여 내 조언을 사용하십시오! – ZachM

+0

FWIW, 당신의 접근 방식은 JNI가'UnregisterNatives'를 가지고있는 이유입니다 -'dlsym()'으로 찾은 기호 중 어느 것이 네이티브 메소드 구현이라면'dlclose()'를 호출하기 전에 등록을 취소 할 수 있습니다. – fadden

관련 문제