Android屏幕旋转导致崩溃

3

PlaceActivity托管两个片段

  1. PlaceDetailsFragment - 其中包含一个视图页 - PlaceSlideFragment
  2. PlaceMapFramgment - 托管Google Maps

当我尝试更改方向时,应用程序崩溃,并显示以下错误日志。

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;
    }
}
3个回答

8

你的Fragment必须有一个空构造函数。

使用setArguments(Bundle)代替直接在构造函数中传递参数。

在你的示例中,删除PlaceSlideFragment.java中的构造函数。而是在onCreateView内部使用:

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

然后,要实例化PlaceSlideFragment,请使用以下代码:

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

或者,如果你将这段代码移动到PlaceSlideFragment的某个静态方法中,效果会更好。

我正在构造函数中从数据库向Viewpager提供数据。 - Harsha M V
1
你不应该这样做,应该使用setArguments方法来实现。 - Tobrun
@HarshaMV 使用 setArguments 传递数据。 - Dmitry Zaytsev
我已更新了我的代码。你能指出我做错了什么吗?我不明白我需要做哪些更改。 - Harsha M V

3
堆栈跟踪包含以下行:

无法实例化片段com.m7.nomad.fragments.PlaceSlideFragment:请确保类名存在、为公共、具有一个公共空构造函数

构造函数存在问题,使用片段的良好方法是使用一个getInstance方法来调用空构造函数。
为什么需要空构造函数?

Android框架将在片段被重新创建时(例如配置更改)调用它们。

如果您对片段有任何其他问题,请在下面发表评论。
编辑:
片段示例
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;
    }
}

在分页中

 @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;
    }

希望这能帮到你,你也可以看一下保留片段和处理配置更改,因为以后可能会遇到其他异常


1
我已经更新了我的代码 - 你能指出如何进行更改吗? - Harsha M V
1
你的代码会因为“NullPointerException”而崩溃。如果你从构造函数中调用“getArguments”,它将返回“null”。 - Dmitry Zaytsev
我遇到了这个错误:在PlaceSlideFragment类中找不到putArguments(Bundle)方法。 - Harsha M V
我认为它是 setArguments。 - Harsha M V

1
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

这行代码显示您没有支持库。

请按以下步骤添加支持库:

右键单击项目 -> Android 工具 -> 添加支持库

然后清理并构建您的项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接