2010-05-09 3 views
8

Я прочитал некоторые документы о загрузчиках классов, но я все еще не уверен, где и зачем они нужны. API Android говорит:Правильное использование Classloader (особенно в Android)

Загружает классы и ресурсы из репозитория . Один или несколько загрузчиков классов установлены во время выполнения. Они относятся к , когда каждый раз, когда система времени выполнения нуждается в определенном классе, который еще не является , доступен в памяти.

Так что, если я понимаю это правильно, может быть много класслайдеров, которые несут ответственность за загрузку новых классов. Но как система решает, что использовать? И в какой ситуации разработчик должен создать экземпляр нового загрузчика классов?

В Android API для Намерения есть метод

public void setExtrasClassLoader (ClassLoader loader) 

Описание говорит:

Устанавливает ClassLoader, который будет использоваться когда демаршаллизацией любых значения Parcelable из статистов в этом Намерение.

Могу ли я определить там специальный загрузчик классов, чтобы я мог передать объект с намерением, которые не определены в принимающей деятельности? Пример:

Если объект A, расположенный в проекте A (в Eclipse), определяет объект, который я хочу отправить в Activity B в Project B с помощью putExtra объекта Intent. Если этот объект, который отправляется через Intent, не определен (исходный код в проекте B), тогда существует исключение NoClassDefFoundException. Могу ли я использовать метод setExtraClassloader, чтобы избежать этого исключения? Если да, как я могу решить, какой объект classloader должен пройти? И как мне его правильно создать?

ответ

9

Я прочитал несколько о документацию загрузчиков классов, но им все еще не уверен, где и зачем они нужны.

Вообще говоря, вам не нужно прикасаться к системе загрузчика классов.

И в какой ситуации следует разработчик экземпляр нового загрузчика классов?

После десятилетнего опыта программирования на Java. :-)

Если активность А, находится в Project A (в Eclipse) определяет объект, который я хочу, чтобы отправить активность B в проекте B с использованием putExtra умысла объекта. Если этот объект , который отправляется по намерению, не указан (исходный код в проекте B), , то существует NoClassDefFoundException. Могу ли я использовать метод setExtraClassloader для избежать этого исключения?

Нет, потому что Project A и Project B не могут использовать код. Поместите класс, который вам нужен, в оба проекта. Или используйте интерфейс удаленной службы с AIDL вместо Intents и дополнительные услуги. Или не используйте пользовательский класс, а скорее обрабатывайте объект как структуру данных (например, используйте простой HashMapStrings или что-то в этом роде).

+0

но если это невозможно, какова цель этого метода?? – RoflcoptrException

+0

Для выполнения действительно причудливых трюков в рамках одного проекта. – CommonsWare

+0

Пользовательские загрузчики классов обычно создают столько проблем, сколько они решают, поэтому они не являются хорошим местом для начала при попытке решить проблему. Если вы действительно хотите смутить, попробуйте выяснить, что делает Thread.setContextClassLoader. :-) – fadden

4

ClassLoaders не так уж трудно понять, по крайней мере, на складе Java. (Я могу научить вас системе ClassLoader за 90 минут - я делаю это все время на шоу No Fluff Just Stuff.) Тем не менее, большую часть времени вам не нужно создавать собственный ClassLoader - если хотите к futz с байт-кодом по пути, java.lang.instrument - ваш друг. Если вы хотите загрузить код из URL-адреса, проверьте java.net.URLClassLoader. Между этими двумя, потребность в пользовательском ClassLoader полностью равна нулю.

7

Это поздний ответ, но, надеюсь, он поможет другим.

Classloaders в целом используются для загрузки исполняемого кода Java во время выполнения. Хорошим примером этого может быть плагин, загружаемый из Интернета. Вы можете взять двоичные данные из файла класса, загрузить его и вызвать функции в нем по мере необходимости. Разумеется, вам нужно использовать интерфейс или абстрактный класс, который известен вызывающей программе, поэтому он знает, как использовать класс.

Пользовательский загрузчик классов используется, когда данные двоичного класса недоступны в типичной усадьбе. Например, если у вас есть устройство Bluetooth, которое содержит файл класса с кодом, реализующим интерфейс, вам нужно будет написать пользовательский загрузчик классов для загрузки данных класса через интерфейс Bluetooth.

Еще одна причина, по которой вы можете написать пользовательский загрузчик классов, - это если вы хотите изменить способ загрузки класса для других классов. Вы можете ограничить, какие внутренние классы загруженному классу имеют доступ или даже писать ваши собственные классы, изменяя поведение внутреннего класса. Например, если загруженный класс использует класс Java.io.File, вам может потребоваться заставить его использовать внутренний класс для доступа к файлам по-другому.

Вкратце, когда вы пишете пользовательский загрузчик классов, вы меняете способ загрузки класса, а также то, как загруженный класс будет загружать все остальные классы.

Смежные вопросы