hamzarh
hamzarh

Reputation: 330

Fragment and AsyncTask

I have got the same problem for 8 days now and i hope that someone can help me, i am working on an application that parse multiple RSS feeds and display them on listview with fragment but the problem is that the UI get blocked for 2 to 4 seconds, and every time the user touches the screen the application crashes. I tracked the problem and i found out that i had to bring the data asynchronously, which i actually did, but every time i have a fragment, the same problem occurs. In fact,the fragment blocks when it brings data if it does it from a main thread, while i actually bring data asynchronously, that's why i can't get the reason for the blocking.

This is how i change my code, this is my interface

public interface OnTaskFinishedListener {
void onTaskFinished(ArrayList<Article> articles);
}

i am getting the ArrayList in the AsyncTask like this

public class AndroidSaxFeedParserAsync extends AsyncTask<String, Long,ArrayList<Article>> {
ArrayList<Article> rssItems = new ArrayList<Article>();

public URL feedUrl;

OnTaskFinishedListener onTaskFinishedListener;

public AndroidSaxFeedParserAsync(OnTaskFinishedListener _onTaskFinishedListener)
{
    onTaskFinishedListener = _onTaskFinishedListener ;
    }

@Override
protected void onPostExecute(ArrayList<Article> result) {
    super.onPostExecute(result);
    onTaskFinishedListener.onTaskFinished(result);
}
@Override
protected ArrayList<Article> doInBackground(String... params) {
//....
    return rssItems;
}   

}

and finally i get it here in my fragment like this

public class FeedPlayerIndexFragment extends SherlockFragment implements OnTaskFinishedListener{

String url="http://www.whatever.com/index.php?format=feed&amp;type=rss";
ArrayList<Article> feeds;
ItemAdapterArticle lfa;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    new AndroidSaxFeedParserAsync(new OnTaskFinishedListener() {
        @Override
        public void onTaskFinished(ArrayList<Article> articles) {
        }
    }).execute(url);
    View view=inflater.inflate(R.layout.main, container, false);
//....
return view;
}

@Override
public void onTaskFinished(ArrayList<Article> articles) {
    lfa = new ItemAdapterArticle(getActivity().getApplicationContext(), articles);  
    }

}

Upvotes: 0

Views: 1797

Answers (1)

Egor
Egor

Reputation: 40203

Problem is that you're using AsyncTask.get() call which is actually blocking. There's another solution on this problem which doesn't block the UI thread. You need to define a simple interface:

public interface OnTaskFinishedListener {
    void onTaskFinished(List<Article> articles);
}

The calling Fragment should implement this interface. When instantiating the AsyncTask you send your Fragment as an OnTaskFinishedListener instance as a parameter to constructor. The AsyncTask should hold the reference to OnTaskFinishedListener instance, and when the work is done, in onPostExecute(), you call onTaskFinished() on the instance. Now, in the Fragment you can respond to this call and use the articles parameter to populate your UI components. Hope this helps.

Upvotes: 2

Related Questions