2013-07-10 50 views
0

我有AsyncTask类,名为LoadXMLData,正如您可以看到的,我在解析XML数据doInBackground()方法。从片段获取AsyncTask结果数据

public class LoadXMLData extends AsyncTask<String, RSSFeed, RSSFeed>{ 

public static final int DIALOG_DOWNLOAD_PROGRESS = 0; 
private ProgressDialog mProgressDialog; 


private Context context; 
RSSFeed feed; 



public LoadXMLData(Context context) { 
    this.context = context; 
    mProgressDialog = new ProgressDialog(context); 
    mProgressDialog.setMessage("Molimo Vas, sačekajte. Podaci se učitavaju."); 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
    mProgressDialog.show(); 
    Log.d("OVDE SAM:", "onPreExecute()"); 
} 

@Override 
protected RSSFeed doInBackground(String... urls) { 
    // Obtain feed 
    DOMParser myParser = new DOMParser(); 
    feed = myParser.parseXml(urls[0]); 
    Log.d("OVDE SAM:", "PARSIRAM XML"); 
    return feed; 
} 



@Override 
protected void onPostExecute(RSSFeed result) { 
    mProgressDialog.dismiss(); 

    super.onPostExecute(result); 
} 

}

我有几个片段,在这里我需要从的AsyncTask获取数据。我怎么能做到这一点?

这是一个片段的代码,称为NajnovijeFragment

public class NajnovijeFragment extends Fragment{ 

GridView lv; 
RSSFeed feed; 
CustomListAdapter adapter; 
private String RSSFEEDURL = "http://balkanandroid.com/feed/"; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_najnovije, container, 
      false);  


    lv = (GridView) view.findViewById(R.id.GridView1); 

    // Set an Adapter to the ListView 
    adapter = new CustomListAdapter(); 
    lv.setAdapter(adapter); 

    // Set on item click listener to the ListView 
    lv.setOnItemClickListener(new OnItemClickListener() { 

     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
       long arg3) { 
      // actions to be performed when a list item clicked 
      int pos = arg2; 

      Bundle bundle = new Bundle(); 
      bundle.putSerializable("feed", feed); 
      Intent intent = new Intent(getActivity(), DetailsActivity.class); 
      intent.putExtras(bundle); 
      intent.putExtra("pos", pos); 
      startActivity(intent); 

     } 
    }); 

    return view; 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    adapter.imageLoader.clearCache(); 
    adapter.notifyDataSetChanged(); 
} 

class CustomListAdapter extends BaseAdapter { 

    private LayoutInflater layoutInflater; 
    public ImageLoader imageLoader; 

    public CustomListAdapter() { 

     layoutInflater = (LayoutInflater) getActivity().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     imageLoader = new ImageLoader(getActivity().getApplicationContext()); 
    } 

    public int getCount() { 
     // TODO Auto-generated method stub 
     // Set the total list item count 
     return feed.getItemCount(); 
    } 

    public Object getItem(int arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     // Inflate the item layout and set the views 
     View listItem = convertView; 
     int pos = position; 
     if (listItem == null) { 
      listItem = layoutInflater.inflate(R.layout.list_item, null); 
     } 

     // Initialize the views in the layout 
     ImageView iv = (ImageView) listItem.findViewById(R.id.thumb); 
     TextView tvTitle = (TextView) listItem.findViewById(R.id.title); 
     TextView tvDate = (TextView) listItem.findViewById(R.id.tvDate); 

     // Set the views in the layout 
     imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv); 
     tvTitle.setText(feed.getItem(pos).getTitle()); 
     tvDate.setText(feed.getItem(pos).getDate()); 

     return listItem; 
    } 

} 

}

回答

4

从ASyncTask获取数据的最简单方法是实现回调。

创建一个接口:

public interface OnXMLLoadFinishedListener { 
    public void onXMLDataReady(RSSFeed results); 
} 

在你LoadXMLData:

private OnXMLLoadFinishedListener listener; 

public void setOnXMLLoadFinishedListener(OnXMLLoadFinishedListener listener){ 
    this.listener = listener; 
} 

@Override 
protected void onPostExecute(RSSFeed result) { 
    super.onPostExecute(result); 
    listener.onXMLDataReady(RSSFeed results); 
} 

在您的片段:

public class NajnovijeFragment extends Fragment implements OnXMLLoadFinishedListener{ 

,并覆盖onXMLDataReady:

@override 
public void onXMLDataReady(RSSFeed results){ 
    //display your data. 
} 

确保当您创建的AsyncTask实例设置监听器,否则这是行不通的:

LoadXMLData xmlLoader = new LoadXMLData(); 
xmlLoader.setOnXMLLoadFinishedListener(this); 
+0

这个工程,谢谢! – Zookey

1

的AsyncTask是一个类,是对UI非常相关的,如果你需要更新与该XML的UI解析你应该采取这样的考虑:

  • 充分利用的AsyncTask片段中的内部类或
  • 将片段传递给您的asynctask
  • 更新onPostExecute()中的片段视图

在任何情况下,你应该检查,如果你的活动是零,如果这样...避免更新的观点,这样的事情:

onPostExecute(Object xml) { 
    if(getActivity != null) { 
     // update Views like... 
     textViewLabel.setText(parsedXml.getTitle); 
    } 
} 

我会建议你使用SafeAsyncTask,这是一个Java类从Roboguice项目中,只有一个文件,它关系到java.util.concurrent.Callable,只需复制并粘贴来源:

SafeAsyncTask.java

How to use it!

+0

我试图用的AsyncTask作为内部类片段类的,但我STIL可以得到的AsyncTask的结果我case RSSFeed feed,因为我在feed.getItemCount()上得到了空指针异常。因为我在RSS Feed feed上得到了空值。 – Zookey

+0

所以这个问题与XML解析器有关,对吧?尝试使用“简单”是一个XML解析器,非常好。检查: http://simple.sourceforge.net/ –

+0

不,一切都很好用XML解析器,问题只是我可以在片段类中得到AsyncTask的结果。 – Zookey

1

您的AsyncTask已经知道上下文,因此您可以在onPostExecute中调用回您的活动(出于说明目的称为ActivityMain)。例如

@Override 
protected void onPostExecute(String result) { 
super.onPostExecute(result); 
((ActivityMain) context).loadCompleteHandler(param1,param2,...) 
} 

然后由您决定如何在您的活动中实现loadCompleteHandler。现在您的活动可能不存在,因此在活动被移除时,您必须小心取消AsyncTask。属于活动的碎片也可以访问该活动。

+0

我没有任何想法如何解决我的问题。 – Zookey

+0

实现loadCompleteHandler来将结果存储在活动的某个地方,并让你的碎片从那里拾取它。 –

+0

你能发表一些代码吗? – Zookey