AndroidのEclipseのlogcatにあるこのメッセージはどういう意味ですか?
W/ActivityThread: ClassLoader.getResources: The class loader returned by Thread.getContextClassLoader() may fail for processes that Host multiple applications. You should explicitly specify a context class loader. For example: Thread.setContextClassLoader(getClass().getClassLoader());
残念ながら、この警告に関するコンテキストが与えられていないため、この問題の原因と解決方法がわかりません。
このメッセージは、AndroidがThread.currentThread().setContextClassLoader()
を使用してダミーのClassLoader
をセットアップし、何かがそのダミーのクラスローダーを使用しようとしていることを意味します。何か多くのことがあり、与えられた情報から正確に何を判断するのは難しいです。しかし、試すことができるトリックがあります。以下を参照してください。とにかく、Androidはダミークラスローダーを設定しますプロセスに複数のAPKからのコードが含まれる可能性がある場合。具体的には、_Android:sharedUserId
_を使用した場合、Androidはマニフェストを検索します:
_<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
...
Android:sharedUserId="triggers.dummy.loader" >
_
または、非標準の_Android:process
_で実行している場合
_ <application Android:process="triggers.dummy.loader">
_
警告を取り除くためにできることは2つあります。
Android:sharedUserId
_または_Android:process
_は使用しないでくださいClassLoader
を明示的に設定しますソリューション2を使用するには、いくつかの重要な洞察が必要です。まず、APKのクラスAnyClass
の場合、AnyClass.class.getClassLoader()
は同じClassLoader
を返します。第二に、
_AnyClass obj = new AnyClass();
Thread.currentThread().setContextClassLoader(obj.getClass().getClassLoader())
_
と同じです
_Thread.currentThread().setContextClassLoader(AnyClass.class.getClassLoader())
_
第三に、Thread.currentThread().setContextClassLoader(getClass().getClassLoader())
を呼び出すコードの前にThread.currentThread().getContextClassLoader()
を呼び出す必要があります。第4に、多くのAPKが関係している場合は、Thread.setContextClassLoader(getClass().getClassLoader())
afterを呼び出す必要があります(そうでない場合、最後のAPKをロードすると、手動で設定したものが上書きされます)。そのため、以下のデバッグトリックを使用して、この場合にコンテキストクラスローダーを使用しているユーザーを見つけることをお勧めします。次に、その直前に、目的のAPK、通常は最初に読み込まれるAPK(または、APKが1つしかない場合は、そのAPK;)のクラスに対してThread.setContextClassLoader(getClass().getClassLoader())
を呼び出します。第5に、コンテキストクラスローダーはスレッドごとです。これは、アプリケーションがマルチスレッドの場合に注意する必要があります。
ClassLoader.getResources()を呼び出すコードを知りたい場合は、次のように機能するはずです。
_Thread.currentThread().setContextClassLoader(new ClassLoader() {
@Override
public Enumeration<URL> getResources(String resName) throws IOException {
Log.i("Debug", "Stack trace of who uses " +
"Thread.currentThread().getContextClassLoader()." +
"getResources(String resName):", new Exception());
return super.getResources(resName);
}
});
_
これを十分に早く行うと、ダミークラスローダーでgetResources()
を呼び出した人に戻るスタックトレースがlogcatに表示されます。
マニフェストにAndroid:sharedUserIdまたはAndroid:processのいずれも含まれていないこの警告を受け取りました...
エミュレーターでのみ表示されることがわかりました...
デバイスは警告メッセージを表示しませんでした。 Smartphone KitKat 4.4 API19およびTablet5.0.1 API21でテスト済み。