Android: "Klasse Loader kann für Prozesse, die mehrere Anwendungen Host"

Was bedeutet diese Nachricht in Eclipse's Logcat für Android?

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()); 

Leider gibt es keinen Kontext für diese Warnung gegeben, also weiß ich nicht, was dieses Problem verursacht und wie ich es lösen kann.

  • Ok, um Fragmente zu aktualisieren, anstatt neue Instanzen zu erstellen?
  • So richten Sie ImageView auf die rechte Seite des LinearLayout programmgesteuert aus
  • Kann ich die Transaktionsinformationen der In-App-Abrechnung direkt mit dem Android Market Server überprüfen?
  • So erstellen Sie eine Bibliothek auf Github und verwenden sie durch Gradle-Abhängigkeiten in Android Studio
  • Checked Items aus Listenansicht in android
  • Runnable ist erfolgreich gepostet, aber nicht laufen
  • Fehler beim Initialisieren von Cordova: Klasse nicht gefunden
  • Wie kann man den Ort des sichtbaren Teils einer Mapview in android anzeigen?
  • Wie man UI-basierte Navigation in Cross-Plattform-Apps behandelt?
  • Speichern von ArrayListen in SQLite-Datenbanken
  • Genymotion Android Emulator für Xamarin
  • Verwenden Sie mehrere Firebase-Konten in einer einzigen Android-App für Google Analytics
  • 2 Solutions collect form web for “Android: "Klasse Loader kann für Prozesse, die mehrere Anwendungen Host"”

    Hintergrundinformation

    Die Nachricht bedeutet, dass Android einen Dummy ClassLoader mit Thread.currentThread().setContextClassLoader() , und etwas versucht, diesen Dummy Class Loader zu verwenden. Das etwas kann eine Menge Dinge sein, es ist schwer zu sagen, was genau aus den Informationen gegeben ist. Es gibt einen Trick, den du probieren kannst, siehe unten. Wie auch immer, Android richtet die Dummy-Klasse Loader, wenn es ein Risiko, dass der Prozess Code von mehr als einem APK enthalten könnte. Genauer gesagt, Android sieht in Ihrem Manifest, wenn Sie android:sharedUserId :

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

    Oder wenn Sie in einem Nicht-Standard- android:process laufen

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

    Wie loswerden die Warnung

    Es gibt zwei Dinge, die du tun kannst, um die Warnung loszuwerden:

    1. Verwenden Sie nicht android:sharedUserId oder android:process
    2. Explizit festlegen, was APK ClassLoader vor dem Ausführen eines anderen Codes verwenden soll

    Um mit Lösung 2 zu gehen, gibt es einige wichtige Erkenntnisse, die du brauchst. Zuerst wird für jede Klasse AnyClass in einer APK AnyClass.class.getClassLoader() denselben ClassLoader . Zweite,

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

    ist das gleiche wie

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

    Drittens müssen Sie Thread.currentThread().setContextClassLoader(getClass().getClassLoader()) vor dem Code, der Thread.currentThread().getContextClassLoader() . Vielen Dank, wenn viele APKs involviert sind, müssen Sie Thread.setContextClassLoader(getClass().getClassLoader()) nachdem das letzte APK geladen wurde (andernfalls wird das letzte APK überschrieben, was man manuell gesetzt hat). Aus diesem Grund wäre es eine gute Idee, herauszufinden, wer den Kontext-Klassen-Loader in Ihrem Fall mit dem folgenden Debug-Trick verwendet. Dann nennen Thread.setContextClassLoader(getClass().getClassLoader()) für eine Klasse aus der gewünschten APK, in der Regel die APK, die zuerst geladen wird (oder, wenn nur eine APK beteiligt ist, dass APK ;). Fünftens ist der Context-Class-Loader pro Thread , den Sie beachten müssen, wenn Ihre Anwendung Multi-Threaded ist.

    Debug-Trick

    Wenn Sie herausfinden möchten, welchen Code ClassLoader.getResources () aufruft, sollte dies funktionieren:

     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); } }); 

    Wenn du das früh genug machst, solltest du in der Logcat eine Stack-Trace sehen, die auf denjenigen zurückkommt, der getResources() auf den Dummy-Class Loader ruft.

    Ich erhielt diese Warnung ohne Android: sharedUserId oder Android: Prozess in meinem Manifest …

    Fand es nur auf einem Emulator …

    Geräte haben die Warnmeldung nicht angezeigt. Geprüft auf Smartphone KitKat 4.4 API 19 und Tablet 5.0.1 API 21.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.