Korrekte Verwendung von Classloader (insbesondere bei Android)
Las ich einige Dokumentationen über classloadern, aber ich bin immer noch nicht sicher, wo und warum Sie gebraucht werden. Die Android-API sagt:
Lädt Klassen und Ressourcen aus einer
repository. Eine oder mehrere class loader
installiert sind zur Laufzeit. Diese sind
konsultiert, wenn die runtime-system
Bedürfnisse einer bestimmten Klasse, die noch nicht
verfügbar im Speicher.
Wenn also verstehe ich das richtig, es gibt viele classlaoders, die verantwortlich für das laden von neuen Klassen. Aber wie entscheidet das system, welche zu benutzen? Und in welcher situation sollte ein Entwickler instanziieren, eine neue classloader?
In der Android-API für Vorsatz gibt es eine Methode,
public void setExtrasClassLoader (ClassLoader loader)
Die Beschreibung sagt:
Setzt den ClassLoader verwendet werden
beim unmarshalling alle Parcelable
Werte aus der extras von dieser Absicht.
Kann ich also definieren, gibt es einen speziellen classloader, so dass ich pass-Objekt mit einer Absicht, die nicht definiert sind, in die empfangende Aktivität? Ein Beispiel:
Wenn Eine Aktivität die sich im Projekt (in Eclipse) definiert ein Objekt, das will ich senden zur Aktivität B in Projekt B mit putExtra dem Intent-Objekt. Wenn das Objekt, das senden über die Absicht ist nicht definiert (source-code im Projekt B), dann gibt es eine NoClassDefFoundException. So kann ich mit der Methode setExtraClassloader zu vermeiden, diese Ausnahme? Wenn ja, wie kann ich entscheiden, welche classloader-Objekt, ich-pass? Und wie instanziiere ich es richtig?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Allgemein gesprochen, Sie müssen nicht berühren Sie den system-classloader.
Nach über einem Jahrzehnt Erfahrung in der Java-Programmierung. 🙂
Nein, da Projekt A und Projekt B nicht teilen kann, code. Legen Sie die Klasse, die Sie müssen in beiden Projekten. Oder verwenden Sie ein remote-service-interface mit AIDL statt
Intents
und extras. Oder verwenden Sie nicht eine eigene Klasse, sondern behandeln das Objekt in einer Datenstruktur (z.B., verwenden Sie eine einfacheHashMap
vonStrings
oder so).createPackageContext
Methode habe ich hier: stackoverflow.com/questions/5743485/...ResultReceiver
zwischen verschiedenen Paketen. Was denkst du? (Es gibt natürlich auch remote-service-interface, aber manchmal ResultReceiver ist einfach bequemer).ResultReceiver
zu arbeiten (zugegeben, ich habe nicht versucht, sehr hart :-). Würde ich erwägenMessenger
stattResultReceiver
, als dass auch istParcelable
ist, muss nicht unbedingt ausgebaut werden (also der classloader-Problem geht Weg), und kann verwendet werden, in der gleichen Rolle alsResultReceiver
.Dies ist eine späte Antwort, aber hoffentlich hilft es anderen.
Classloadern, im Allgemeinen, laden Sie die ausführbaren Java-code zur Laufzeit. Ein gutes Beispiel HIERFÜR wäre ein plugin, das aus dem internet heruntergeladen wird. Sie können die binären Daten aus einer class-Datei, laden Sie es, und rufen Sie die Funktionen innerhalb der it-Bedarf. Sie tun, natürlich, müssen eine Schnittstelle oder abstrakte Klasse, die bekannt ist durch das aufrufende Programm, damit es weiß, wie es um die Klasse zu verwenden.
Einen custom classloader verwendet wird, wenn der Binär-Klasse, die Daten nicht zugänglich ist in einem typischen Herrenhaus. Zum Beispiel, wenn Sie ein bluetooth-Gerät enthält eine Klasse Datei mit code, der Implementierung einer Schnittstelle, benötigen Sie zum schreiben eines benutzerdefinierten classloader zum laden der Klasse, die Daten über die bluetooth-Schnittstelle.
Weiterer Grund, möchten Sie vielleicht schreiben Sie einen benutzerdefinierten classloader ist, wenn Sie ändern möchten, wie die geladene Klasse greift auf andere Klassen. Sie können einschränken, welche interne Klassen der geladenen Klasse hat Zugriff auf oder sogar Ihre eigenen Klassen schreiben, eine änderung des Verhaltens einer internen Klasse. Zum Beispiel, wenn die geladene Klasse verwendet die Java.io.File-Klasse, müssen Sie möglicherweise zu zwingen, es zu verwenden eine interne Klasse für den Zugriff auf Dateien in einer anderen Art und Weise.
Kurz, wenn Sie schreiben einen custom classloader, die Sie ändern, wie eine Klasse geladen wird, als auch, wie die geladene Klasse wird geladen, alle anderen Klassen.
Classloadern gar nicht so schwer zu verstehen, zumindest im Java-Lager-Raum. (Ich kann Ihnen beibringen, den ClassLoader system in 90 Minuten-so mache ich es die ganze Zeit auf der No Fluff Just Stuff zeigt.) Das heißt, die meisten der Zeit, die Sie nicht brauchen, um erstellen Sie einen benutzerdefinierten ClassLoader-wenn Sie möchten, futz mit bytecode auf dem Weg in, java.lang.instrument ist dein Freund. Wenn Sie möchten, laden code aus einer URL, check-out java.net.URLClassLoader. Zwischen diesen beiden, die Notwendigkeit für einen custom ClassLoader ist völlig Fehlanzeige.