Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTask runs on each page of the ViewPager

I have 3 Tabs like in the android development tutorial

Now what I want to do is very simple I use Fragments on each page. I want to show different content from a rss feed on each page.

The problem is when I go to the next tab it runs AsyncTask (which is in onCreateView) of the previous Fragment.

So you start on Page 1 it loads the content fine. Then when you go to Page 2 is runs the onCreateView of the Fragment of Page 1 again. And obviously gives an NullException. The point is it should not be running AsyncTask of Page 1 at all at that Page 2.

I don't think there is any example code needed if so tell me which part you need to see. Then I will edit my question.

AsyncTask inside a ListFragment :

public class MyAsyncTask extends AsyncTask<List<String>, Void, List<String>>
{
    // List of messages of the rss feed
    private List<Message> messages;
    private volatile boolean running = true;

    @SuppressWarnings("unused")
    private WeakReference<NieuwsSectionFragment> fragmentWeakRef;

    private MyAsyncTask(NieuwsSectionFragment fragment)
    {
        this.fragmentWeakRef = new WeakReference<NieuwsSectionFragment>(fragment);
    }
    @Override
    protected void onPreExecute() 
    {
        super.onPreExecute();

        mProgress.show();
       //  progress.setVisibility(View.VISIBLE); //<< set here
    }
    @Override
    protected void onCancelled()
    {
        Log.w("onCancelled", "now cancelled");
        running = false;
    }
    @Override
    protected List<String> doInBackground(List<String>... urls)
    {
        FeedParser parser = FeedParserFactory.getParser();
        messages = parser.parse();
        List<String> titles = new ArrayList<String>(messages.size());
        for (Message msg : messages)
        {
            titles.add(msg.getTitle());
            // Log.w("doInBackground", msg.getTitle());
        }
        return titles;
    }

    @Override
    protected void onPostExecute(List<String> result)
    {
        super.onPostExecute(result);            
        mProgress.dismiss();
        if (result != null)
        {
            PostData data = null;
            listData = new PostData[result.size()];
            for (int i = 0; i < result.size(); i++)
            {
                data = new PostData();                  
                data.postTitle = result.get(i);
                data.postThumbUrl = "http://igo.nl/foto/app_thumb/28991-Taxi-vast-na-poging-tot-nemen-van-sluiproute.jpg";                  
                listData[i] = data;
                Log.w("onPostExecute", "" + listData[i].postTitle);
            }
            adapter = new PostItemAdapter (getActivity(), android.R.layout.simple_list_item_1, listData);               
            setListAdapter(adapter);
            adapter.notifyDataSetChanged(); 
        }
    }
}

It's called inside a method and that method is executed inside the onCreateView of the ListFragment :

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    startNewAsyncTask();
    View rootView = inflater.inflate(R.layout.fragment_section_nieuws, container, false);
    return rootView;
}

@SuppressWarnings("unchecked")
public void startNewAsyncTask()
{       
    MyAsyncTask asyncTask = new MyAsyncTask(this);
    this.asyncTaskWeakRef = new WeakReference<MyAsyncTask>(asyncTask);
    asyncTask.execute();
}

The LogCat : logcat

like image 575
Shishi Avatar asked Feb 10 '14 08:02

Shishi


People also ask

Which AsyncTask runs on background thread?

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .

How many times an instance of AsyncTask can be executed?

AsyncTask instances can only be used one time.

What is AsyncTask?

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

What is the use of ViewPager?

Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of a PagerAdapter to generate the pages that the view shows. ViewPager is most often used in conjunction with android.


3 Answers

Try using isAdded() before onPostExecute(). isAdded() returns true if the fragment is currently added to its activity.

http://developer.android.com/reference/android/app/Fragment.html#isAdded()

@Override
protected void postExecute(){
    if(isAdded()){
        //perform Display Changes
    }
}
like image 140
Deepak Negi Avatar answered Oct 19 '22 20:10

Deepak Negi


Move your

startNewAsyncTask(); 

to onActivityCreated()

like image 2
localhost Avatar answered Oct 19 '22 20:10

localhost


I'm assuming your using FragmentPagerAdapter with your ViewPager.

To enable smooth animations, the ViewPager by default keeps the current fragment and the two neighbors in resumed state. So onCreateView is not the best place to start the AsyncTask.

Instead you need to create a custom listener interface. The fragments in the ViewPager should implement it, and call the new interface from the ViewPager's OnPageChangeListener.

Check out my answer to this question or you can read the whole tutorial here.

like image 1
LordRaydenMK Avatar answered Oct 19 '22 21:10

LordRaydenMK