我有一个名为 LoadXMLData 的AsyncTask类,正如您所看到的,我在 doInBackground()方法中解析XML数据。
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;
}
}
}
答案 0 :(得分: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);
答案 1 :(得分:1)
AsyncTask是一个与UI非常相关的类,如果您需要使用此XML解析来更新UI,您应该考虑这一点:
在任何情况下,你应该检查你的活动是否为空,如果是这样的话......避免更新视图,如下所示:
onPostExecute(Object xml) {
if(getActivity != null) {
// update Views like...
textViewLabel.setText(parsedXml.getTitle);
}
}
我建议你使用SafeAsyncTask,这是一个来自Roboguice Project的java类,只有一个文件,它与java.util.concurrent.Callable有关,只需复制并粘贴源代码:
答案 2 :(得分:1)
您的AsyncTask已经知道了上下文,因此您可以在onPostExecute中回调您的活动(为了说明目的而称为ActivityMain)。 e.g。
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
((ActivityMain) context).loadCompleteHandler(param1,param2,...)
}
然后由您决定如何在活动中实现loadCompleteHandler。现在您的活动可能不存在,因此在删除活动时必须小心取消AsyncTask。属于某个活动的碎片也可以访问该活动。