4

Android 以外の人への前置きとして (一部の Linux の人は、この情報で答えを知っているかもしれません):

Android のすべてのアプリケーションは、Dalvik 仮想マシンのインスタンスで実行されます。アプリケーションを起動すると、ActivityManager と呼ばれるエンティティがパイプに書き込み、別のエンティティである Zygote にアプリを起動する必要があることを通知します。Zygote は、ライブラリがプリロードされた空の状態の Dalvik VM インスタンスであり、パイプ経由で呼び出されると、自身のクローンを作成し、クローンは、起動するアプリに関連付けられた Linux ユーザーに対して権限レベルを下げます。これにより、アプリを起動するときの時間とメモリが節約されます。すべてのライブラリを再読み込みして毎回すべてのセットアップを行うという代替案を検討してください。

私の問題は、独自のバージョンのライブラリを使用したいので、この特定のプロセスで閉じたい Zygote に読み込まれている特定のライブラリがあることです。ネイティブ コードを MY .so ファイルにリンクしました。このファイルは適切なフォルダーにコピーされ、アプリケーションの起動時に Java レイヤー "System.load('xyz')" を介して読み込まれますが、コードが実行されると、.so ファイルが呼び出されます。私のものではなく、元のシステムのライブラリの機能。「cat /proc/NNNN/maps」を実行すると、私のライブラリと同様に古いライブラリがメモリ内にあることがわかります。

アプリケーションでその特定のライブラリを閉じる方法はありますか? そうでない場合、そのライブラリ内の関数へのすべての呼び出しが古いバージョンではなく MY バージョンに確実に渡されるようにする方法はありますか?

ありがとう!

4

1 に答える 1

3

( を使用して) 共有ライブラリを閉じるのはdlclose()、ライブラリのコードのマップを解除するため、最善の状況ではトリッキーです。後で何かがそのコード (おそらく C++ デストラクタ) を呼び出すと、プログラムはすぐにクラッシュします。ライブラリはあなた以外のコードによってロードされているため、マップを解除した瞬間に別のスレッドがそのライブラリでコードを実行している可能性があり、再びクラッシュが発生します。

だから、それをしないでください。:-)

ライブラリのバージョンを静的ライブラリとしてビルドし、それをコードに直接リンクできる場合は、問題を完全に回避できるはずです。

FWIW、さまざまなライブラリ (特に SSL と ICU) が Dalvik にリンクされており、zygote によって明示的に読み込まれるわけではないため、それらのいずれかを置き換えようとすると、/system/libzygote からフォークされているかどうかに関係なく、バージョンが取得されます。

于 2013-04-22T18:03:56.087 に答える