Gaurav
Gaurav

Reputation: 3749

ClasscastException on Application Start

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

Answers (2)

A--C
A--C

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

TouchBoarder
TouchBoarder

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

Related Questions