0

我有一个有 5 个片段的 FragmentActivity

我的第二个片段是一个显示许多图像的网格视图。

该 GridFragment 正在启动一个带有回调的 AsyncTask 以获取图像的数组列表。

然后它使用以下作为参数(侦听器、上下文、数组列表)设置适配器上下文是 getActivity()

当适配器启动时,它会尝试执行 LayoutInflater.from(Context);

那就是我得到我的空指针的地方。如果异步任务完成,它不会崩溃。但是我在异步任务运行时旋转它崩溃了。

有没有办法解决?

分段

public class IconsFrag extends GridFragmentIcons implements AdapterIcons.AdapterListener {

    AsyncTaskIconsAll aTask;
    Button button;
    final String TAG = "IconsFrag";
    private ArrayList<Integer> mThumbs;
    private final String KEY_LIST_DATA = "icons_cache";
    private final String KEY_LIST_POSITION = "icons_position";
    private int mPosition = -1;
    private AdapterIcons mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.i(TAG, "onActivityCreated");
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null){
            Log.i(TAG, "savedInstanceState null");
            aTask = new AsyncTaskIconsAll();
            aTask.updateActivity(this, getActivity(), new AsyncTaskIconsAll.Callback() {
                @Override
                public void onData(ArrayList<Integer> data) {
                    mThumbs = data;

                    mAdapter = new AdapterIcons(IconsFrag.this, getActivity(), mThumbs);
                    getGridView().setNumColumns(getResources().getInteger(R.integer.column_count_icon));
                    setGridAdapter(mAdapter);
                    getGridView().setOnItemClickListener(null);
                }
            });
            aTask.execute();
        }

异步任务

public class AsyncTaskIconsAll extends AsyncTask<Void, Integer, ArrayList<Integer>> {

    private Activity mContext;
    private Fragment mFragment;
    private ArrayList<Integer> mThumbs;
    final String TAG = "AsyncTaskIconsAll";
    Callback mCallback;

    public static interface Callback{
        public void onData(ArrayList<Integer> data);
    }

    public void updateActivity(Fragment f, Activity a, final Callback c) {
        Log.i(TAG, "updateActivity");
        mContext = a;
        mFragment = f;
        mCallback = c;
        if(mThumbs != null)
            Log.i(TAG, "Callback not null");
            mCallback.onData(mThumbs);
    }

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected ArrayList<Integer> doInBackground(Void... unused){
        Log.i(TAG, "doInBackground");
        mThumbs = new ArrayList<Integer>();
        final String[] extras = mContext.getResources().getStringArray(R.array.icon_pack);
            for (String extra : extras) {
                String uri = "drawable/" + extra;
                int res = mContext.getResources().getIdentifier(uri, null, mContext.getPackageName());
                if (res != 0) {
                    mThumbs.add(res);
                }
            }
        return mThumbs;
    }

    protected void onProgressUpdate(Integer... progress) {

    }

    @Override
    protected void onPostExecute(ArrayList<Integer> icons) {
        Log.i(TAG, "onPostExecute");
        mThumbs = icons;
        mCallback.onData(mThumbs);
        ProgressBar mProgess = (ProgressBar) mFragment.getView().findViewById(R.id.pending);
        mProgess.setVisibility(mFragment.getView().GONE);
    }
}

适配器

public class AdapterIcons extends BaseAdapter implements SpinnerAdapter {

    private final String TAG = "AdapterIcons";
    private AdapterListener mListener;
    private ArrayList<?> mData;
    private final LayoutInflater mInflater;

    public AdapterIcons(AdapterListener listener, Activity activity) {
        this.mData = new ArrayList<Object>();
        this.mInflater = LayoutInflater.from(activity);
        this.mListener = listener;
    }

    public AdapterIcons(AdapterListener listener, Context Context, ArrayList<?> data) {
        this.mData = (data == null) ? new ArrayList<Object>() : data;
        this.mInflater = LayoutInflater.from(Context);
        this.mListener = listener;
    }

    public ArrayList<?> getData () {
        return this.mData;
    }

    public void setData (ArrayList<?> data) {
        this.mData = data;
    }

    public void clearData () {
        this.mData.clear();
    }

    public static abstract interface AdapterListener
    {
        public abstract View getView(int paramInt, View paramView, ViewGroup paramViewGroup);
    }

    public Intent.ShortcutIconResource getResource(int position){
        Icons icons= new Icons();
        ArrayList<Integer> list = (ArrayList<Integer>) mData;
        return Intent.ShortcutIconResource.fromContext(icons.getBaseContext(), list.get(position));
    }

    @Override
    public int getCount () {
        if (mData == null)
            Log.d(TAG, "getCount() Data Set Is Null");
        return (mData != null) ? mData.size() : 0;
    }

    @Override
    public Object getItem (int position) {
        if (mData == null)
            Log.d(TAG, "getItem(int position) Data Set Is Null");
        return (mData != null) ? mData.get(position) : null;
    }

    @Override
    public long getItemId (int position) {
        if (mData == null)
            Log.d(TAG, "getItemId(int position) Data Set Is Null");
        return (mData != null) ? position : 0;
    }

    @Override
    public View getView (int position, View convertView, ViewGroup parent) {
        return (mListener == null) ? new LinearLayout(mInflater.getContext()) : this.mListener.getView(position, convertView, parent);
    }

    @Override
    public View getDropDownView (int position, View convertView, ViewGroup parent) {
        return (mListener == null) ? new LinearLayout(mInflater.getContext()) : this.mListener.getView(position, convertView, parent);
    }

}
4

3 回答 3

0

因此,在onPostExecute()您尝试将项目添加到(暂时)被破坏的活动中。检查您是否getActivity() == null在使用上下文做任何事情之前。就像是:

public void onPostExecute(){

    if(getActivity() == null){
        // activity is destroyed... skip
        return;
    }

    // proceed like normal

}

这是我在没有代码的情况下能做的最好的事情。祝你好运

于 2013-11-13T16:42:04.640 回答
0

你有没有注意到你应该在这里使用方括号 {},否则mCallback.onData(mThumbs)总是会被调用:

if(mThumbs != null){
        Log.i(TAG, "Callback not null");
        mCallback.onData(mThumbs);
}

此外,您在创建 asyncTask 时传递了fragmentactivityin asyncTaskupdateActivity()方法,但是当您旋转设备时它们将为空,活动将被重新创建,因此当您在 asyncTask 中使用它们时doInBackground()onPostExecute()您必须先检查它们是否不为空,否则您可能会遇到 NullPointerException。

于 2013-11-13T16:51:22.027 回答
0

看看这个答案。这几乎是同样的问题。您需要处理默认情况下更改活动状态的方向更改(如果您不覆盖)。

https://stackoverflow.com/a/7618739/1080954

于 2013-11-13T16:40:30.377 回答