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:
LocalBroadcastManagerMessengerAfter 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