suresh cheemalamudi
suresh cheemalamudi

Reputation: 6240

Android On Orientation Change Crash

PlaceActivity hosts Two Fragments

  1. PlaceDetailsFragment - Which has a view pager - PlaceSlideFragment
  2. PlaceMapFramgment - host Google Maps

When i try to change the orientation the app crashes with the following Error Log.

01-12 15:24:57.950: E/AndroidRuntime(30412): FATAL EXCEPTION: main
01-12 15:24:57.950: E/AndroidRuntime(30412): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.m7.nomad/com.m7.nomad.PlaceActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3363)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.access$700(ActivityThread.java:127)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1163)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.os.Looper.loop(Looper.java:137)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.main(ActivityThread.java:4507)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at java.lang.reflect.Method.invokeNative(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at java.lang.reflect.Method.invoke(Method.java:511)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at dalvik.system.NativeStart.main(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412): Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.support.v4.app.Fragment.instantiate(Fragment.java:405)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1767)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:208)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at com.m7.nomad.PlaceActivity.onCreate(PlaceActivity.java:34)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.Activity.performCreate(Activity.java:4465)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
01-12 15:24:57.950: E/AndroidRuntime(30412):    ... 12 more
01-12 15:24:57.950: E/AndroidRuntime(30412): Caused by: java.lang.InstantiationException: can't instantiate class com.m7.nomad.fragments.PlaceSlideFragment; no empty constructor
01-12 15:24:57.950: E/AndroidRuntime(30412):    at java.lang.Class.newInstanceImpl(Native Method)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at java.lang.Class.newInstance(Class.java:1319)
01-12 15:24:57.950: E/AndroidRuntime(30412):    at android.support.v4.app.Fragment.instantiate(Fragment.java:394)
01-12 15:24:57.950: E/AndroidRuntime(30412):    ... 19 more

PlaceSlidesFragemntsAdapter.java

public class PlaceSlidesFragmentAdapter extends FragmentPagerAdapter  {

    DBAdapter db = new DBAdapter(SplashActivity.context);
    List<String> photoList = new ArrayList<String>();

    private int mCount;

    public PlaceSlidesFragmentAdapter(FragmentManager fm) {
        super(fm);

        db.open();
        Cursor photosCursor = db.getPhotos(PlaceActivity.placeId);

        // Iterate Through the Place Cursor
        if (photosCursor.moveToFirst()) {
            do {
                photoList.add(photosCursor.getString(1));
            } while (photosCursor.moveToNext());
        }

        db.close();

        mCount = photoList.size();
    }

    @Override
    public Fragment getItem(int position) {
        return new PlaceSlideFragment(photoList.get(position));
    }

    @Override
    public int getCount() {
        return mCount;
    }

    public void setCount(int count) {
        if (count > 0 && count <= 10) {
            mCount = count;
            notifyDataSetChanged();
        }
    }
}

PlaceSlideFragment.java

public final class PlaceSlideFragment extends Fragment {
    String imageResourceId;

    public PlaceSlideFragment(String i) {
        imageResourceId = i;
    }

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

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        ImageView image = new ImageView(getActivity());

        ImageLoader imgLoader = new ImageLoader(MainActivity.context);
        imgLoader.DisplayImage(imageResourceId, new Activity(), image);

        LinearLayout layout = new LinearLayout(getActivity());
        layout.setLayoutParams(new LayoutParams());

        layout.setGravity(Gravity.CENTER);
        layout.addView(image);

        return layout;
    }
}

Upvotes: 3

Views: 3846

Answers (3)

Tobrun
Tobrun

Reputation: 18391

The stacktrace contains the following line

Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public

There is a problem with the constructor, a good practice with fragments is using a getInstance method that will call the empty constructor.

Why the need of empty constructor?

Android framework will call these when fragments are recreated e.g. configuration change

If you have any other problems with fragments comment below

EDIT:

FRAGMENT EXAMPLE

public final class PlaceSlideFragment extends Fragment {

    public static Fragment newInstance() {
      return new PlaceSlideFragment();
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        ImageView image = new ImageView(getActivity());
        ImageLoader imgLoader = new ImageLoader(MainActivity.context);
        imgLoader.DisplayImage(getArguments().getInt("key"), new Activity(), image);

        LinearLayout layout = new LinearLayout(getActivity());
        layout.setLayoutParams(new LayoutParams());

        layout.setGravity(Gravity.CENTER);
        layout.addView(image);

        return layout;
    }
}

IN PAGER

 @Override
    public Fragment getItem(int position) {
        PlaceSlideFragment frag = PlaceSlideFragment.newInstance();
        Bundle args = new Bundle()
        args.putInt("key",ID_RESOURCE_HERE);
        frag.setArguments(args);
        return frag;
    }

I hope this helps, you can also take a look a retaining fragments and handling configuration changes since you will probably run into other exceptions later on

Upvotes: 3

Dmitry Zaytsev
Dmitry Zaytsev

Reputation: 23972

Your Fragment must have an empty constructor.

Use setArguments(Bundle) instead of passing parameters to constructor directly.

In your example in PlaceSlideFragment.java remove constructor. Instead, inside onCreateView use:

imageResourceId = getArguments().getString("param");

Then, to instantinate PlaceSlideFragment use this code:

Fragment f = new PlaceSlideFragment();
Bundle args = new Bundle();
args.putString("param", yourParam);
f.setArguments(args);

or it will be even better if you'll move this code into some static method of PlaceSlideFragment

Upvotes: 8

Nirav Tukadiya
Nirav Tukadiya

Reputation: 3417

Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.m7.nomad.fragments.PlaceSlideFragment: make sure class name exists, is public, and has an empty constructor that is public

This line shows that you doesn't have support library. Add support library as below:

Right Click Project -> Android Tools -> Add Support Library

and then clean and build your Project.

Upvotes: 1

Related Questions