21

EclipseのAndroid用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());

残念ながら、この警告に関するコンテキストが与えられていないため、この問題の原因と解決方法がわかりません。

4

2 に答える 2

35

背景情報

このメッセージは、AndroidがでダミーをセットアップClassLoaderThread.currentThread().setContextClassLoader()、何かがそのダミークラスローダーを使用しようとしていることを意味します。何かがたくさんある可能性があり、与えられた情報から正確に何を伝えるのは難しいです。ただし、試すことができるトリックがあります。以下を参照してください。とにかく、プロセスに複数のAPKからのコードが含まれる可能性がある場合、Androidはダミークラスローダーをセットアップします。具体的には、以下を使用したことがある場合、Androidはマニフェストを調べますandroid:sharedUserId

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:sharedUserId="triggers.dummy.loader" >

または非標準で実行している場合android:process

    <application android:process="triggers.dummy.loader">

警告を取り除く方法

警告を取り除くためにできることは2つあります。

  1. android:sharedUserIdまたはを使用しないでくださいandroid:process
  2. ClassLoader他のコードを実行する前に、使用するAPKを明示的に設定します

ソリューション2を使用するには、いくつかの重要な洞察が必要です。AnyClassまず、 APK内のすべてのクラスについてAnyClass.class.getClassLoader()、同じを返しClassLoaderます。2番、

AnyClass obj = new AnyClass();
Thread.currentThread().setContextClassLoader(obj.getClass().getClassLoader())

と同じです

Thread.currentThread().setContextClassLoader(AnyClass.class.getClassLoader())

Thread.currentThread().setContextClassLoader(getClass().getClassLoader())第三に、を呼び出すコードの前に呼び出す必要がありますThread.currentThread().getContextClassLoader()Thread.setContextClassLoader(getClass().getClassLoader()) 第4に、多くのAPKが関係している場合は、最後のAPKがロードされた後に呼び出す必要があります(そうでない場合、最後のAPKをロードすると、手動で設定したものが上書きされます)。そのため、以下のデバッグトリックを使用して、この場合にコンテキストクラスローダーを使用しているユーザーを特定することをお勧めします。次に、その直前にThread.setContextClassLoader(getClass().getClassLoader())、目的のAPK、通常は最初にロードされるAPK(または、APKが1つしかない場合は、そのAPK;)からクラスを呼び出します。第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に表示されます。

于 2012-11-19T13:48:53.140 に答える
0

マニフェストにandroid:sharedUserIdまたはandroid:processがなくてもこの警告が表示されました...

エミュレーターでのみ表示されることがわかりました...

デバイスは警告メッセージを表示しませんでした。Smartphone KitKat 4.4API19およびTablet5.0.1API21でテスト済み。

于 2016-08-30T11:08:50.473 に答える