2013-04-22 4 views
8

Я делаю некоторые практические чтения на AsyncTaskLoader, поэтому я могу использовать эту технику для загрузки списка контактов. Единственный раз, когда работает код, я реализую обратные вызовы из класса, который расширяет Fragment, как в MyLoader extends Fragment implements LoaderCallbacks<ArrayList<Contact>>. Есть ли другой способ? Все, что мне действительно нужно, это список контактов (имя, телефон, миниатюра) для отправки на мой сервер. Когда, например, я пытаюсь использовать Context, так как я могу получить это из любой активности, просто делая (Context)this, код не может даже скомпилироваться. В контексте я имею в видуИспользование LoaderCallbacks без фрагмента

context.getLoaderManager().initLoader(1, null, this); 
//I already changed to Fragment so don't really remember the exact ".context" line. 
//But someone who has done this will understand the snippet. 

BTW: Я использую несколько ссылок. Один из них - http://developer.android.com/reference/android/content/AsyncTaskLoader.html.

ВОПРОС (еще раз): Можно ли использовать AsyncTaskLoader без фрагмента или фрагментации?

код, который работает с ФРАГМЕНТ:

package com.example.contactpreload.utils; 

import java.util.ArrayList; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.LoaderManager.LoaderCallbacks; 
import android.support.v4.content.Loader; 

public class LoadingContacts extends Fragment implements LoaderCallbacks<ArrayList<Contact>> { 
    ArrayList<Contact> loadedContacts; 
    static Fragment fragmentActivity; 

    public static LoadingContacts newInstance(int arg) { 

     LoadingContacts f = new LoadingContacts(); 
     Bundle bundle = new Bundle(); 
     bundle.putInt("index", arg); 
     f.setArguments(bundle); 
     fragmentActivity = new Fragment(); 
     return f; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     System.out.println("onCreate()"); 
     int mIndex = getArguments().getInt("index"); 
     System.out.println(mIndex); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     System.out.println("onActivityCreated()"); 
     getLoaderManager().initLoader(1, null, this); 
    } 

    @Override 
    public Loader<ArrayList<Contact>> onCreateLoader(int arg0, Bundle arg1) { 

     System.out.println("onCreateLoader()"); 
     return new ContactsLoader(getActivity()); 
    } 

    @Override 
    public void onLoadFinished(Loader<ArrayList<Contact>> loader, ArrayList<Contact> data) { 
     loadedContacts = data; 
     System.out.println("AND THE CONTACTS ARE: "); 
     for (Contact c : loadedContacts) { 
      System.out.println("NAME: " + c.getName()); 
      System.out.println("getPhoneNumberHome: " + c.getPhoneNumber()); 
     } 

    } 

    @Override 
    public void onLoaderReset(Loader<ArrayList<Contact>> arg0) { 
     System.out.println("onLoaderReset()"); 
     // TODO Auto-generated method stub 

    } 

} 



package com.example.contactpreload; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.view.Menu; 

import com.example.contactpreload.utils.LoadingContacts; 

public class MainActivity extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     LoadingContacts fragment = LoadingContacts.newInstance(1); 
     fragment.setRetainInstance(true); 
     getSupportFragmentManager().beginTransaction() 
      .add(android.R.id.content, fragment).commit(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

} 

МАНИФЕСТ:

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="16" /> 
+0

@bossylobster, я пытаюсь ответить на этот вопрос, но я его не взламываю. Любой вход? Как насчет ваших коллег? То, что получает меня, - это часть 8-го уровня. Он действительно работает с фрагментом, но ни с чем другим (см. Обсуждение ниже в ответе wangyif2). –

ответ

7

AsyncTaskLoader не имеет ничего общего с ли вы используете Fragment или Activity.

Чтобы дать вам пример, рассмотрим список деятельности:

public class ExampleActivity extends ListActivity implements 
LoaderManager.LoaderCallbacks<Cursor> { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.todo_list); 

     //to start the loader: 
     getLoaderManager().initLoader(0, null, this); 
    } 

    //override the loader callback methods as usual 
    // Creates a new loader after the initLoader() call 
    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     CursorLoader cursorLoader = new CursorLoader(this, 
     uri, projection, null, null, null); 
     return cursorLoader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     adapter.swapCursor(data); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     // data is not available anymore, delete reference 
     adapter.swapCursor(null); 
    } 
} 

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

Кроме того, убедитесь, что все ваши импорта последовательны, либо используя support.v4 библиотеку или библиотеку регулярных:

import android.app.LoaderManager; 
import android.content.CursorLoader; 
import android.content.Loader; 

Другой вопрос, который задают, является то, что если интерфейс LoaderCallback может использоваться автономно. Это не рекомендуется, если вы считаете, что это LoaderCallback.

The LoaderManager.LoaderCallbacks<D> interface is a simple contract that the LoaderManager uses to report data back to the client. Что это означает, его единственная задача - загрузить некоторые данные в фоновом режиме, запрошенные клиентом, что является эффективным действием.

Если вы создаете отдельный класс, вы можете расширить определение класса для реализации LoaderManager.LoaderCallbacks<D>, но вам нужно будет сообщить загруженные данные обратно в исходную деятельность с помощью какого-то механизма, что осложнило бы простую задачу.

Теперь, если вы действительно устремлены на этом, вы можете создать свой класс автономный, как так:

public class LoadingContacts implements LoaderManager.LoaderCallbacks<Cursor> { 
@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    return null; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
} 
} 

В вашем методе onLoadFinished, вам нужно будет отправить загруженную Cursor обратно либо через эфир, или своего рода сообщение автобуса:

  • LocalBroadcastManager
  • Otto
  • Messenger

После отправки этой информации в MainActivity, вы можете загрузить его к адаптеру и по-прежнему, как есть.

+1

Большое спасибо за ваш ответ: +1. Теперь я добавил код, который работает с фрагментом и фрагментацией. Не возражаете ли вы отредактировать его в своем ответе, чтобы показать, как он будет работать, если «LoadingContacts» не имеет родительской активности (например, Fragment) и «MainActivity» не расширил FragmentActivity? – learner

+2

Позвольте мне понять ваш вопрос, вы хотите, чтобы «MainActivity» расширил «Activity» и «LoadingContacts», чтобы быть просто загрузчиком, а не «Activity» или «Fragment»? – wangyif2

+3

Я любопытно посмотреть, как это будет работать. –

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