Android AsyncTask only loaded one item into ArrayAdapter?
This only loads on of the titles in the url
It should load all of the items in this list
http://www.gamespy.com/index/release.html
private class fetcher extends AsyncTask<Void,Void,Void>{
@Override
protected void onPreExecute(){
dialog = ProgressDialog.show(HtmlparserExampleActivity.this, "",
"Loading. Please wait...", true);
dialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
//Setting the list of gameRelease Arrays
Document doc = null;
try {
doc = Jsoup.connect("http://www.gamespy.com/index/release.html").get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(doc == null){
}
else{
// Get all td's that are a child of a row - each game has 4 of these
Elements games = doc.select("tr> td.indexList1, tr > td.indexList2");
// Iterator over those elements
ListIterator<Element> postIt = games.listIterator();
//Loads all the items until there is no .hasNExt()
while (postIt.hasNext()) {
while (postIt.hasNext()) {
// Add the game text to the ArrayList
Element name = postIt.next();
nameString = name.text();
//Get the platform
platform = postIt.next().text();
//Get the URL
Element url = name.select("a").first();
urlString = url.attr("href");
//Get the Genre of the game
genre = postIt.next().text();
//Get the release date
releaseDate = postIt.next().text();
Log.v("Title", nameString);
//Instantiating the GameReleaseAdapter
}
}
}
return null;
}
@Override
protected void onPostExecute(Void notUsed){
dialog.dismiss();
ArrayList<GameRelease> gameList = new ArrayList<GameRelease>();
HtmlparserExampleActivity.this.setListAdapter(new GameReleaseAdapter(HtmlparserExampleActivity.this, gameList));
//Instantiating the GameReleaseAdapter
//Set the detals on the game releases to the setter and getter class GameRelease
gameList.add(new GameRelease(nameString, platform, genre, releaseDate, urlString));
}
}
}
When an item in the list is clicked i get this exception
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): FATAL EXCEPTION: main
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): at java.util.ArrayList.get(ArrayList.java:311)
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:298)
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): at com.fttech.htmlParser.HtmlparserExampleActivity$1.onItemClick(HtmlparserExampleActivity.java:68)
08-16 22:15:52.736: ERROR/AndroidRuntime(30528): at android.widget.AdapterView.performItemClick(AdapterView.java:284)
EDIT: Adapter Code
private class GameReleaseAdapter extends ArrayAdapter<GameRelease> {
//Setting the GameRelease to a single item
private ArrayList<GameRelease> items;
//Make the layout for the items
public GameReleaseAdapter(Context context, ArrayList<GameRelease> items) {
// TODO: make a layout for each item which you'd call (for example) itemLayout
super(context, R.layout.item, items);
this.items = items;
}
//Inflate the layout to override getView.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO: return an item view styled however you want or as shown in the tutorial
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
//Setting the texts to there rightful TextViews.
GameRelease o = items.get(position);
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
TextView plat = (TextView)v.findViewById(R.id.platform);
TextView genre = (TextView)v.findViewById(R.id.genre);
tt.setText(o.getName());
bt.setText("RELEASE DATE: " +o.getReleaseDate());
plat.setText("PLATFORM: " + o.getPlatform());
genre.setText("GENRE: " + o.getGenre());
//Returning the View v which inflates the layout row.xml each time a item is added.
return v;
}
EDIT: I now get this erro IndexOutOfBounds..
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): FATAL EXCEPTION: main
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): java.lang.IndexOutOfBoundsException: Invalid index 39, size is 1
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): at java.util.ArrayList.get(ArrayList.java:308)
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:341)
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): at com.fttech.htmlParser.HtmlparserExampleActivity$1.onItemClick(HtmlparserExampleActivity.java:82)
08-17 00:41:10.340: ERROR/AndroidRuntime(14481): 开发者_如何学编程 at android.widget.AdapterView.performItemClick(AdapterView.java:282)
EDIT: Here is my onItemCLick method
this.getListView().setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//The debug is pointing me to this line
GameRelease selectedGameRelease = myGameReleaseAdapter .getItem(position);
String urlString = selectedGameRelease.getUrl();
//Make what you like with the url
Toast.makeText(HtmlparserExampleActivity.this, urlString, Toast.LENGTH_SHORT).show();
Intent i = new Intent(HtmlparserExampleActivity.this, releaseInfo.class);
i.putExtra("url", urlString);
startActivity(i);
}
});
}
class Fetcher extends AsyncTask<Void, Void, Void>{
private ArrayList<GameRelease> list;
protected void onPreExecute(){
list = new ArrayList<GameRelease>();
dialog.show();
}
protected void doInBackground(Void... args){
// html parsing here
while(postIt.hasNext()){
// create a new GameRelease object for each entry you get from parsing
list.add(new GameRelease(nameString, platform, genre, releaseDate, urlString));
}
}
protected void onPostExecute(Void notUsed){
dialog.dismiss;
GameReleaseAdapter mAdapter = new GameReleaseAdapter(HtmlparserExampleActivity.this, list);
setListAdapter(mAdapter);
}
}
That's the logic I think is correct. Or you can the setListAdapter()
with an empty ArrayList
in onCreate()
. Then you don't have to create the ArrayList
inside AsyncTask
but adding items to it then onPostExecute()
you call notifyDataSetChanged()
. But first I suggest you try with this flow
I thought it was odd for you to have two nested while() loops doing exactly the same thing...seems like it might be overkill. Did you mean for the inner while loop to be looping through an inner element of the document instead of repeating over the same items a second time?
精彩评论