2013-11-13 2 views
0

У меня есть FragmentActivity, который имеет 5 ФрагментыЗапуск AsynTask в GridFragment вызывает нулевой указатель на поворот

На мой 2-й фрагмент является GridView, который отображает множество изображений.

Этот GridFragment запускает AsyncTask с обратным вызовом, чтобы получить архиватор изображений.

Затем он устанавливает адаптер, используя следующие в качестве аргументов (слушатель, контекст, ArrayList) контекст getActivity()

когда адаптер начинает он пытается сделать LayoutInflater.from (контекста);

Вот где я получаю свой пустой указатель. Если задача async завершена, она не будет аварийно завершена. но он вращается, а задача async работает.

Есть ли способ обойти это?

Фрагмент

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(); 
     } 

AsyncTask

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

} 
+1

разместить свой код здесь – Raghunandan

ответ

0

Взгляните на этот ответ. Это почти такая же проблема. Вам необходимо обработать изменения ориентации, которые изменяют состояние активности по умолчанию (если вы не переопределяете).

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

0

так в вашем onPostExecute() попытке добавить элементы в деятельности, которая (временно) уничтожены. Проверьте, есть ли ваш getActivity() == null, прежде чем делать материал с контекстом. Что-то вроде:

public void onPostExecute(){ 

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

    // proceed like normal 

} 

Это лучшее, что я могу сделать без кода. Успехи

+1

обновленного пост с кодом – Bignadad

0

Вы заметили, что вы должны использовать скобки {} здесь, в противном случае mCallback.onData(mThumbs) всегда будет называться:

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

Также вы пропускание fragment и activity в AsyncTask updateActivity() метода при создании asyncTask, но при повороте устройства они будут пустыми, активность будет воссоздана, поэтому, когда вы используете их в asyncTask doInBackground() и onPostExecute(), сначала вы должны проверить, не являются ли они нулевыми, иначе вы могли бы получить исключение NullPointerException ,

+0

обновленного постом с кодовым – Bignadad

+0

@Bignadad ответа изменил –

+0

Спасибо за этот совет, который поможет, когда mthumbs уже создана. но для проблемы im, имеющей mthumbs, является null. если пользователь поворачивает устройство, а mthumbs строит его сбой – Bignadad

Смежные вопросы