填充类碎片异常(FC)时出错

时间:2012-03-31 17:14:33

标签: android eclipse

正如你们所知道的那样 - 我的prorgrmming经验有限 - 无论如何,在这个级别。我最近几天一直在努力解决这个错误,因为我不确切地知道logcat试图说些什么。你能帮助我吗? (是的,此代码的很大一部分是从AOSP回购中复制而来的。我正在努力使其适应我的需求。)

你们可以提供的任何东西都将非常感谢

logcat的:

03-31 12:49:07.814: D/AndroidRuntime(8809): Shutting down VM
03-31 12:49:07.834: W/dalvikvm(8809): threadid=1: thread exiting with uncaught exception (group=0x40a4f1f8)
03-31 12:49:07.854: E/AndroidRuntime(8809): FATAL EXCEPTION: main
03-31 12:49:07.854: E/AndroidRuntime(8809): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.senseimods.wallpapers.heavymetals/com.senseimods.wallpapers.heavymetals.HeavyMetalsActivity}: android.view.InflateException: Binary XML file line #4: Error inflating class fragment
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.os.Looper.loop(Looper.java:137)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread.main(ActivityThread.java:4424)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at java.lang.reflect.Method.invokeNative(Native Method)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at java.lang.reflect.Method.invoke(Method.java:511)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at dalvik.system.NativeStart.main(Native Method)
03-31 12:49:07.854: E/AndroidRuntime(8809): Caused by: android.view.InflateException: Binary XML file line #4: Error inflating class fragment
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Activity.setContentView(Activity.java:1835)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at com.senseimods.wallpapers.heavymetals.HeavyMetalsActivity.onCreate(HeavyMetalsActivity.java:15)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Activity.performCreate(Activity.java:4465)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
03-31 12:49:07.854: E/AndroidRuntime(8809):     ... 11 more
03-31 12:49:07.854: E/AndroidRuntime(8809): Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.senseimods.heavymetals.WallpaperChooserDialogFragment: make sure class name exists, is public, and has an empty constructor that is public
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Fragment.instantiate(Fragment.java:581)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Fragment.instantiate(Fragment.java:549)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Activity.onCreateView(Activity.java:4235)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
03-31 12:49:07.854: E/AndroidRuntime(8809):     ... 21 more
03-31 12:49:07.854: E/AndroidRuntime(8809): Caused by: java.lang.ClassNotFoundException: com.senseimods.heavymetals.WallpaperChooserDialogFragment
03-31 12:49:07.854: E/AndroidRuntime(8809):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
03-31 12:49:07.854: E/AndroidRuntime(8809):     at android.app.Fragment.instantiate(Fragment.java:571)
03-31 12:49:07.854: E/AndroidRuntime(8809):     ... 24 more
03-31 12:54:07.937: I/Process(8809): Sending signal. PID: 8809 SIG: 9

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.senseimods.wallpapers.heavymetals"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/application_name" >
        <activity
            android:name=".HeavyMetalsActivity"
            android:label="@string/application_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            </activity>

            <activity
                android:name=".WallpaperChooserDialogFragment"
                android:label="@string/application_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>

    </application>

</manifest>

扩展器:

package com.senseimods.wallpapers.heavymetals;

import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
import android.os.Bundle;

public class HeavyMetalsActivity extends Activity {
    private static final String TAG = "WallpaperChooser";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.wallpaper_chooser_base);
        Fragment fragmentView = getFragmentManager().findFragmentById(
                R.id.wallpaper_chooser_fragment);
        // TODO: The following code is currently not exercised. Leaving it here
        // in case it
        // needs to be revived again.
        if (fragmentView == null) {
            /*
             * When the screen is XLarge, the fragment is not included in the
             * layout, so show it as a dialog
             */
            DialogFragment fragment = WallpaperChooserDialogFragment
                    .newInstance();
            fragment.show(getFragmentManager(), "dialog");
        }
    }
}

启动活动:

private static final String TAG = "WallpaperChooserDialogFragment";
    private static final String EMBEDDED_KEY = "com.senseimods.wallpapers."
            + "WallpaperChooserDialogFragment.EMBEDDED_KEY";

    private boolean mEmbedded;
    private Bitmap mBitmap = null;

    private ArrayList<Integer> mThumbs;
    private ArrayList<Integer> mImages;
    private WallpaperLoader mLoader;
    private WallpaperDrawable mWallpaperDrawable = new WallpaperDrawable();

    public static WallpaperChooserDialogFragment newInstance() {
        WallpaperChooserDialogFragment fragment = new WallpaperChooserDialogFragment();
        fragment.setCancelable(true);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null
                && savedInstanceState.containsKey(EMBEDDED_KEY)) {
            mEmbedded = savedInstanceState.getBoolean(EMBEDDED_KEY);
        } else {
            mEmbedded = isInLayout();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putBoolean(EMBEDDED_KEY, mEmbedded);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (mLoader != null
                && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
            mLoader.cancel(true);
            mLoader = null;
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        /*
         * On orientation changes, the dialog is effectively "dismissed" so this
         * is called when the activity is no longer associated with this dying
         * dialog fragment. We should just safely ignore this case by checking
         * if getActivity() returns null
         */
        Activity activity = getActivity();
        if (activity != null) {
            activity.finish();
        }
    }

    /*
     * This will only be called when in XLarge mode, since this Fragment is
     * invoked like a dialog in that mode
     */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        findWallpapers();

        // TODO: The following code is not exercised right now and may be
        // removed
        // if the dialog version is not needed.
        /*
         * final View v = getActivity().getLayoutInflater().inflate(
         * R.layout.wallpaper_chooser, null, false);
         * 
         * GridView gridView = (GridView) v.findViewById(R.id.gallery);
         * gridView.setOnItemClickListener(this); gridView.setAdapter(new
         * ImageAdapter(getActivity()));
         * 
         * final int viewInset =
         * getResources().getDimensionPixelSize(R.dimen.alert_dialog_content_inset
         * );
         * 
         * FrameLayout wallPaperList = (FrameLayout)
         * v.findViewById(R.id.wallpaper_list); AlertDialog.Builder builder =
         * new AlertDialog.Builder(getActivity());
         * builder.setNegativeButton(R.string.wallpaper_cancel, null);
         * builder.setTitle(R.string.wallpaper_dialog_title);
         * builder.setView(wallPaperList, viewInset, viewInset, viewInset,
         * viewInset); return builder.create();
         */
        return null;
    }

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

        /*
         * If this fragment is embedded in the layout of this activity, then we
         * should generate a view to display. Otherwise, a dialog will be
         * created in onCreateDialog()
         */
        if (mEmbedded) {
            View view = inflater.inflate(R.layout.wallpaper_chooser, container,
                    false);
            view.setBackgroundDrawable(mWallpaperDrawable);

            final Gallery gallery = (Gallery) view.findViewById(R.id.gallery);
            gallery.setCallbackDuringFling(false);
            gallery.setOnItemSelectedListener(this);
            gallery.setAdapter(new ImageAdapter(getActivity()));

            View setButton = view.findViewById(R.id.set);
            setButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    selectWallpaper(gallery.getSelectedItemPosition());
                }
            });
            return view;
        }
        return null;
    }

    private void selectWallpaper(int position) {
        try {
            WallpaperManager wpm = (WallpaperManager) getActivity()
                    .getSystemService(Context.WALLPAPER_SERVICE);
            wpm.setResource(mImages.get(position));
            Activity activity = getActivity();
            activity.setResult(Activity.RESULT_OK);
            activity.finish();
        } catch (IOException e) {
            Log.e(TAG, "Failed to set wallpaper: " + e);
        }
    }

    // Click handler for the Dialog's GridView
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        selectWallpaper(position);
    }

    // Selection handler for the embedded Gallery view
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position,
            long id) {
        if (mLoader != null
                && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
            mLoader.cancel();
        }
        mLoader = (WallpaperLoader) new WallpaperLoader().execute(position);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    private void findWallpapers() {
        mThumbs = new ArrayList<Integer>(24);
        mImages = new ArrayList<Integer>(24);

        final Resources resources = getResources();
        // Context.getPackageName() may return the "original" package name,
        // com.cyanogenmod.trebuchet; Resources needs the real package name,
        // com.cyanogenmod.trebuchet. So we ask Resources for what it thinks the
        // package name should be.
        final String packageName = resources
                .getResourcePackageName(R.array.wallpapers);

        addWallpapers(resources, packageName, R.array.wallpapers);
        addWallpapers(resources, packageName, R.array.extra_wallpapers);
    }

    private void addWallpapers(Resources resources, String packageName, int list) {
        final String[] extras = resources.getStringArray(list);
        for (String extra : extras) {
            int res = resources.getIdentifier(extra, "drawable", packageName);
            if (res != 0) {
                final int thumbRes = resources.getIdentifier(extra + "_small",
                        "drawable", packageName);

                if (thumbRes != 0) {
                    mThumbs.add(thumbRes);
                    mImages.add(res);
                    // Log.d(TAG, "add: [" + packageName + "]: " + extra + " ("
                    // + res + ")");
                }
            }
        }
    }

    private class ImageAdapter extends BaseAdapter implements ListAdapter,
            SpinnerAdapter {
        private LayoutInflater mLayoutInflater;

        ImageAdapter(Activity activity) {
            mLayoutInflater = activity.getLayoutInflater();
        }

        public int getCount() {
            return mThumbs.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view;

            if (convertView == null) {
                view = mLayoutInflater.inflate(R.layout.wallpaper_item, parent,
                        false);
            } else {
                view = convertView;
            }

            ImageView image = (ImageView) view
                    .findViewById(R.id.wallpaper_image);

            int thumbRes = mThumbs.get(position);
            image.setImageResource(thumbRes);
            Drawable thumbDrawable = image.getDrawable();
            if (thumbDrawable != null) {
                thumbDrawable.setDither(true);
            } else {
                Log.e(TAG, "Error decoding thumbnail resId=" + thumbRes
                        + " for wallpaper #" + position);
            }

            return view;
        }
    }

    class WallpaperLoader extends AsyncTask<Integer, Void, Bitmap> {
        BitmapFactory.Options mOptions;

        WallpaperLoader() {
            mOptions = new BitmapFactory.Options();
            mOptions.inDither = false;
            mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
        }

        @Override
        protected Bitmap doInBackground(Integer... params) {
            if (isCancelled())
                return null;
            try {
                return BitmapFactory.decodeResource(getResources(),
                        mImages.get(params[0]), mOptions);
            } catch (OutOfMemoryError e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap b) {
            if (b == null)
                return;

            if (!isCancelled() && !mOptions.mCancel) {
                // Help the GC
                if (mBitmap != null) {
                    mBitmap.recycle();
                }

                View v = getView();
                if (v != null) {
                    mBitmap = b;
                    mWallpaperDrawable.setBitmap(b);
                    v.postInvalidate();
                } else {
                    mBitmap = null;
                    mWallpaperDrawable.setBitmap(null);
                }
                mLoader = null;
            } else {
                b.recycle();
            }
        }

        void cancel() {
            mOptions.requestCancelDecode();
            super.cancel(true);
        }
    }

    /**
     * Custom drawable that centers the bitmap fed to it.
     */
    static class WallpaperDrawable extends Drawable {

        Bitmap mBitmap;
        int mIntrinsicWidth;
        int mIntrinsicHeight;

        /* package */void setBitmap(Bitmap bitmap) {
            mBitmap = bitmap;
            if (mBitmap == null)
                return;
            mIntrinsicWidth = mBitmap.getWidth();
            mIntrinsicHeight = mBitmap.getHeight();
        }

        @Override
        public void draw(Canvas canvas) {
            if (mBitmap == null)
                return;
            int width = canvas.getWidth();
            int height = canvas.getHeight();
            int x = (width - mIntrinsicWidth) / 2;
            int y = (height - mIntrinsicHeight) / 2;
            canvas.drawBitmap(mBitmap, x, y, null);
        }

        @Override
        public int getOpacity() {
            return android.graphics.PixelFormat.OPAQUE;
        }

        @Override
        public void setAlpha(int alpha) {
            // Ignore
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            // Ignore
        }
    }
}

3 个答案:

答案 0 :(得分:0)

关键是:

Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.senseimods.heavymetals.WallpaperChooserDialogFragment: make sure class name exists, is public, and has an empty constructor that is public

您违反了以下三条规则之一:

  • 班级必须存在
  • 课程必须公开
  • 该类必须具有公共空构造函数

您也可能违反了第四条规则:

  • 试图假装某些不展开Fragment的内容是Fragment

我这样说是因为您的清单中有一个<activity>元素,声明WallpaperChooserDialogFragment是一个活动,而不是一个片段。

如果WallpaperChooserDialogFragmentFragment,除了修复导致崩溃的错误之外(请参阅上面的项目符号列表),您需要删除<activity>元素,因为它是错。

如果WallpaperChooserDialogFragment不是Fragment,而是活动,您可能希望将该类重命名为不包含Fragment,并且您无法尝试将其强制转换为a DialogFragment或以其他方式将其视为片段。

答案 1 :(得分:0)

我也觉得inflateException一样,不能instataniate错误, 但在我的情况下,这是由于android包重命名。 如果您还重命名了包名称然后面临这个问题,那么R.java和一些条目仍然可能更旧,只需在包名称上输入F2&amp;重命名它不是解决方案。 你用ctrl + f搜索包名&amp;每个人都正确地重命名....

答案 2 :(得分:0)

如果在调用android.view.InflateException: Binary XML file line: #... Error inflating class fragment之前在片段内部使用getActivity()进行操作,则可能会发生onActivityCreated()异常。在这种情况下,您会收到错误的活动参考,并且不能依赖它。

例如,下一个模式是错误的:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) 
{
    final View view = inflater.inflate(R.layout..., container, false);

    Button button = getActivity().findViewById(R.id...);
    button.setOnClickListener(...); - another problem: button is null

    return view;
}