0

私は5つのフラグメントを持つFragmentActivityを持っています

私の 2 番目のフラグメントには、多くの画像を表示するグリッドビューがあります。

その 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

ここで角かっこ {} を使用する必要があることに気付きましたか? そうしないmCallback.onData(mThumbs)と、常に呼び出されます:

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

また、asyncTask を作成するときに asyncTaskメソッドにfragmentとを渡していますが、デバイスを回転させると null になります。アクティビティが再作成されるため、asyncTask でそれらを使用する場合、最初に確認する必要があります。そうしないと、NullPointerException が発生する可能性があります。activityupdateActivity()doInBackground()onPostExecute()

于 2013-11-13T16:51:22.027 に答える
0

そのため、onPostExecute()(一時的に) 破棄されたアクティビティにアイテムを追加しようとします。getActivity() == nullコンテキストを操作する前に確認してください。何かのようなもの:

public void onPostExecute(){

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

    // proceed like normal

}

これは、もうコードなしでできる最善の方法です。幸運を

于 2013-11-13T16:42:04.640 に答える