I am doing some hands-on reading on AsyncTaskLoader so I can use the technique to load the contact list. The only time the code works is when I implement the callbacks from a class that extends Fragment
as in MyLoader extends Fragment implements LoaderCallbacks<ArrayList<Contact>>
. Is there another way? All I really need is the contact list (name, phone, thumbnail), to send to my backend. When, for example, I try to use Context
, since I can get that from any activity by simply doing (Context)this
, the code fails to even compile. By context I mean
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: I am using multiple references. One is http://developer.android.com/reference/android/content/AsyncTaskLoader.html.
QUESTION (again): Can I use AsyncTaskLoader without Fragment or FragmentActivity?
THE CODE THAT WORKS WITH THE FRAGMENT:
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;
}
}
MANIFEST:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
AsyncTaskLoader has nothing to do with whether you are using a Fragment
or an Activity
.
To give you an example, consider a list 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);
}
}
Obviously you need to create corresponding adapter for the list view and layout, but the example just shows you how a simple loader for cursor would work for an Activity.
Also, make sure all your import are consistent, either using the support.v4
library, or the regular library:
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
Another question that is asked, is that if the LoaderCallback
interface can be used standalone. This is not recommended if you consider that the LoaderCallback
is for.
The LoaderManager.LoaderCallbacks<D>
interface is a simple contract that the LoaderManager uses to report data back to the client. What that means, is its only job is to load some data in the background requested by a client, which is effectively, an activity.
If you create a standalone class, you could extend the class definition to implement LoaderManager.LoaderCallbacks<D>
, but you will need to report the loaded data back to the original activity through some kind of mechanism, which would complicated a simple task.
Now if you are really fixed on doing this, you could create your standalone class as so:
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) {
}
}
In your onLoadFinished
method, you will need to send the loaded Cursor
back through either a broadcast, or some kind of message bus:
LocalBroadcastManager
Messenger
After you send this information to the MainActivity
, you can load it to the adapter and continue as is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With