2012-03-20 1 views
7

У меня есть активность, которая использует два Loaders. Каждый из них возвращает данные другого типа. Чтобы получить данные из одного загрузчика, вы просто реализуете LoaderCallbacks<D> в Activity. Наверное, я мог бы просто реализовать LoaderCallbacks<Object> и проверить тип объекта, а затем решить, какой из двух LoaderCallbacks он есть, но мне кажется, что он взломан (в основном из-за отсутствия безопасности типа здесь).LoaderCallbacks как статический внутренний класс (для обработки нескольких загрузчиков с разными типами данных)

Так что я подумал о том, что LoaderCallbacks объект статический внутренний класс, что-то вроде этого:

private static class geocoderLoaderCallbacks implements LoaderCallbacks<List<Address>>{ 

    @Override 
    public Loader<List<Address>> onCreateLoader(int arg0, Bundle arg1) { 
     GeocoderTask loader = new GeocoderTask(context, ""); 
     return loader; 
    } 

    @Override 
    public void onLoadFinished(Loader<List<Address>> loader, List<Address> data) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onLoaderReset(Loader<List<Address>> loader) { 
     // TODO Auto-generated method stub 

    } 


} 

а затем с помощью lm.initLoader(0, null, geocoderLoaderCallbacks).

Возникает два вопроса: нормально ли это делать, или я должен придерживаться реализации LoaderCallbacks в Activity? И как мне безопасно передать контекст в onCreateLoader? Должен ли я просто создать конструктор в geocoderLoaderCallbacks и передать контекст там, как это lm.initLoader(0, null, geocoderLoaderCallbacks(this))?

Здесь есть аналогичный вопрос LoaderManager with multiple loaders: how to get the right cursorloader, но он не объясняет, как управлять двумя загрузчиками с разными типами данных.

ответ

9

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

Передача Context в конструкторе в порядке, если вы не сохраняете статические или другие ссылки на кеширование.

+1

Я не уверен, если я «сохраню статические или другие ссылки на кеширование». Контекст необходим, потому что нужен AsyncTaskLoader. Поэтому я должен передать его в geocoderLoaderCallbacks. Но должен ли я создать его в своей деятельности и передать ссылку на эту конкретную деятельность? Не будет ли это утечка активности? Во всех примерах реализации (где Activity реализует LoaderCallbacks) они используют 'lm.initLoader (0, null, this);' ('this'), чтобы передать ссылку на активность. Затем он автоматически обрабатывается AsyncTaskLoader. Но работает ли он так же со статическим внутренним классом? –

+1

Выполнение этого в другом классе и передача «Контекста» безопасны в отношении утечек, так как срок службы класса обратного вызова загрузчика привязан к времени жизни самой активности. После того, как Activity будет собирать мусор, все ссылки, исходящие оттуда, тоже будут. Единственное, что вы не должны делать, это использовать переменные 'static', которые имеют некоторую ссылку на вашу активность. У вас обычно не будет проблем с утечками, если вы просто используете предоставленные классы по назначению. – zapl

+0

Отлично, спасибо! И +1 для упоминания не использовать статические переменные со ссылкой на Activity –