Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragments, AsyncTask and Listeners

This is something I've been having issues recently. Sometimes after I exit the app using home button and let it sit idly in the background for a while, I get null pointer for getActivity(). So I'm just wondering if I'm setting up async task and listeners wrong or perhaps the issue lies elsewhere. My general procedure is as follows:

public class MyAsyncTask extends AsyncTask<Void, Void, List<SomeObject>>{

    private Context ctx;
    private AsyncListener listener;

    public MyAsyncTask(Context ctx){
    //set Context, etc
    }

 ...
    onPostExecute(List<SomeObject> result){
        super.onPostExecute(result);
        if(result!=null){
            listener.onAvailable(result);
        } else {
            listener.onUnavailable();
        }
    }

    public interface AsyncListener{
        void onAvailable(List<SomeObject> result);
        void onUnavailable();
    }

    public void setAsyncListener(AsyncListener listener){
        this.listener = listener;
    }
}

Fragment:

public class MyFragment extends Fragment implements AsyncListener {

    private AsyncTask task;
    private List<SomeObject> data;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_messages, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        setViews();
        if(data == null) {
            task = new AsyncTask(getActivity());
            task.setAsyncListener(this);
            task.execute();
        } else {
            setData();
        }
    }

    private void setData(){
         someListView.setAdapter(new SomeAdapter(getActivity(), data));
    }

    @Override
    public void onAvailable(List<SomeObject> result){
        this.data = result;
        setData();
    }

    @Override
    public void onUnavailable(List<SomeObject> result){
        //Create toast or alert dialog, etc
   }

}

As you can see, I use listeners to post result from asynctask to my fragment. Problem is, I sometimes receive null pointer on getActivity() when setting adapter. This only happens if I exit application, let it sit in the background for extended period of time and then open it. Perhaps listener gets triggered before Fragment is attached? Perhaps I need to set my logic in a different way?

like image 858
Tomislav Turcic Avatar asked Nov 10 '22 06:11

Tomislav Turcic


1 Answers

The problem lies in this piece of code

private void setData(){
     someListView.setAdapter(new SomeAdapter(getActivity(), data));
}

When you close the activity it may die in the background. When the Asynctask finishes and the SetData function is called from the listener it gets null for getActivity() as it has been destroyed by the OS. Check for getActivity() for null before setting the adapter.

like image 68
Vishal Avatar answered Nov 15 '22 06:11

Vishal