Reputation: 3749
I am trying to use LoaderManager for API <11. I tried to find the error by using Log utility. But no such record is found in logcat. Here is the code. Application simply tries to retrieve data from Contacts. Possible reasons for the classcastexception are to cast incompatible types, I believe there is not such problem in the code. Any help would be appreciated.
package com.example.androidcontact;
import android.net.Uri;
import android.os.Bundle;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
public class MainActivity extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>{
private SimpleCursorAdapter mAdapter;
String tag = "";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreated");
mAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_2,
null,
new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME},
new int[]{android.R.id.text1, android.R.id.text2},
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[]projection = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME};
return new CursorLoader(getActivity(), uri, projection, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
mAdapter.swapCursor(arg1);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
}
Please, do not get me wrong. I just spent the time on how to get the stack trace. I still dont know how to get one for an exception that occurs at the start. Here is the content I could find.
02-19 00:35:35.401: W/dalvikvm(533): threadid=1: thread exiting with uncaught exception (group=0x40015560)
02-19 00:35:43.417: E/AndroidRuntime(533): FATAL EXCEPTION: main
02-19 00:35:43.417: E/AndroidRuntime(533): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.androidcontact/com.example.androidcontact.MainActivity}: java.lang.ClassCastException: com.example.androidcontact.MainActivity
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1569)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.os.Handler.dispatchMessage(Handler.java:99)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.os.Looper.loop(Looper.java:123)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-19 00:35:43.417: E/AndroidRuntime(533): at java.lang.reflect.Method.invokeNative(Native Method)
02-19 00:35:43.417: E/AndroidRuntime(533): at java.lang.reflect.Method.invoke(Method.java:507)
02-19 00:35:43.417: E/AndroidRuntime(533): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-19 00:35:43.417: E/AndroidRuntime(533): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-19 00:35:43.417: E/AndroidRuntime(533): at dalvik.system.NativeStart.main(Native Method)
02-19 00:35:43.417: E/AndroidRuntime(533): Caused by: java.lang.ClassCastException: com.example.androidcontact.MainActivity
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
02-19 00:35:43.417: E/AndroidRuntime(533): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1561)
02-19 00:35:43.417: E/AndroidRuntime(533): ... 11 more
As per the manifest file, I needed the app to run on GingerBread so,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidcontact"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name="android.app.Application"
>
<activity
android:name="com.example.androidcontact.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Upvotes: 0
Views: 667
Reputation: 36449
Your current issue is that you're trying to start a Fragment as an Activity, which doesn't work as you have seen firsthand. Change your class so it looks like this:
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle b)
{
super.onCreate(b);
setContentView (R.layout.main);
}
public static class MyFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>{
private SimpleCursorAdapter mAdapter;
String tag = "";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreated");
mAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_2,
null,
new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME},
new int[]{android.R.id.text1, android.R.id.text2},
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(mAdapter);
getActivity().getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[]projection = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME};
return new CursorLoader(getActivity(), uri, projection, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
mAdapter.swapCursor(arg1);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
}
}
then in res/layout
make a layout file called main.xml
have it contain:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id ="@+id/my_fragment"
android:name="com.example.androidcontact.MainActivity$MyFragment">
</fragment>
Also incorporate @hsigmond's suggestion since you are using the support library (code above already has this change).
Upvotes: 0
Reputation: 6492
You need to use the Support Loader Manager from the support library
getActivity().getSupportLoaderManager().initLoader(0, null, this);
for backward compatibility.
Upvotes: 1