2010-05-09 19 views
8

He leído algunos documentos sobre cargadores de clases, pero todavía no estoy seguro de dónde y por qué se necesitan. La API de Android dice:Uso correcto de Classloader (especialmente en Android)

Carga clases y recursos de un repositorio . Uno o más cargadores de clase se instalan en tiempo de ejecución. Estos son consultados cuando el sistema de tiempo de ejecución necesita una clase específica que aún no está disponible en la memoria.

Así que si entiendo esto correctamente, puede haber muchos clasificadores que son responsables de cargar nuevas clases. Pero, ¿cómo el sistema decide cuál usar? ¿Y en qué situación debería un desarrollador crear una instancia de un nuevo cargador de clases?

En la API de Android para el intento no es un método

public void setExtrasClassLoader (ClassLoader loader) 

La descripción dice:

Establece el cargador de clases que se utilizará cuando unmarshalling cualquier valores parcelable de los extras de esta Intención.

Entonces, ¿puedo definir allí un cargador de clases especial para que pueda pasar el objeto con un Intento que no está definido en la actividad de recepción? Un ejemplo:

Si la actividad A que se encuentra en el Proyecto A (en Eclipse) define un objeto que deseo enviar a la Actividad B en el Proyecto B usando putExtra del objeto Intención. Si este objeto que se envía a través del Intento no está definido (código fuente en el proyecto B), entonces hay una NoClassDefFoundException. Entonces, ¿puedo usar el método setExtraClassloader para evitar esta excepción? En caso afirmativo, ¿cómo puedo decidir qué objeto de cargador de clases tengo que aprobar? ¿Y cómo lo instauro correctamente?

Respuesta

9

leí algunas documentaciones sobre cargadores de clases, pero im todavía no está seguro dónde y por qué son necesarias.

En general, no necesita tocar el sistema del cargador de clases.

Y en qué situación se debe a un desarrollador instanciar un nuevo cargador de clases?

Después de una década de experiencia en la programación de Java. :-)

Si la actividad A, que se encuentra en Proyecto A (en Eclipse) define un objeto la que quiero enviar a Actividad B en el proyecto B usando putExtra del objeto Intención. Si este objeto que se envía a través del Intento no está definido (código fuente en el proyecto B), , entonces hay una NoClassDefFoundException. Entonces, ¿puedo usar el método setExtraClassloader a para evitar esta excepción?

No, porque el Proyecto A y el Proyecto B no pueden compartir el código. Pon la clase que necesitas en ambos proyectos. O utilice una interfaz de servicio remoto con AIDL en lugar de Intents y extras. O no use una clase personalizada, sino más bien trate el objeto como una estructura de datos (por ejemplo, use un simple HashMap de Strings o algo así).

+0

pero si esto no es posible, ¿cuál es el propósito de este método'? – RoflcoptrException

+0

Para hacer trucos realmente extravagantes dentro de un solo proyecto. – CommonsWare

+0

Los cargadores de clases personalizados generalmente crean tantos problemas como resuelven, por lo que no son un buen lugar para comenzar cuando intentan resolver un problema. Si realmente quiere confundirse, intente descubrir qué hace Thread.setContextClassLoader. :-) – fadden

4

Los ClassLoaders no son tan difíciles de entender, al menos en el stock de espacio de Java. (Puedo enseñarte el sistema ClassLoader en 90 minutos; lo hago todo el tiempo en los programas No Fluff Just Stuff). Dicho esto, la mayoría de las veces no necesitas crear un ClassLoader personalizado, si quieres para futz con bytecode en el camino, java.lang.instrument es tu amigo. Si desea cargar código desde una URL, consulte java.net.URLClassLoader. Entre esos dos, la necesidad de un ClassLoader personalizado es completamente nula.

7

Esta es una respuesta tardía, pero es de esperar que ayude a los demás.

Los cargadores de clases en general, se utilizan para cargar código Java ejecutable en tiempo de ejecución. Un buen ejemplo de esto sería un complemento que se descarga desde Internet. Puede tomar los datos binarios de un archivo de clase, cargarlos y llamar a las funciones que contiene, según sea necesario. Por supuesto, necesita utilizar una interfaz o clase abstracta conocida por el programa de llamadas para que sepa cómo usar la clase.

Se utiliza un cargador de clases personalizado cuando no se puede acceder a los datos de la clase binaria en un feudo típico. Por ejemplo, si tiene un dispositivo bluetooth que contiene un archivo de clase con código que implementa una interfaz, necesitará escribir un cargador de clases personalizado para cargar los datos de clase a través de la interfaz bluetooth.

Otra razón por la que desea escribir un cargador de clases personalizado es si desea cambiar la forma en que la clase cargada accede a otras clases. Puede restringir a qué clases internas tiene acceso la clase cargada o incluso escribir sus propias clases, cambiando el comportamiento de una clase interna. Por ejemplo, si la clase cargada usa la clase Java.io.File, puede necesitar forzarla para que use una clase interna para acceder a los archivos de una manera diferente.

En resumen, cuando escribe un cargador de clases personalizado, cambia la forma en que se carga una clase, así como también cómo la clase cargada cargará todas las demás clases.