2013-07-10 82 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