我制作了一些JSON解析器,我想在同一个ListView中显示信息。我尝试使用AsynkTask但它没有用。
对于ListView,我创建了从ArrayAdapter扩展的简单类Plase和Adapter。
有我的代码:
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
public class ListActivity extends Activity {
private static final String API_START = "http://api.yelp.com/business_review_search?location=";
private static final String API_END = "&ywsid=mlNrKepTs01H6gB0yoIWrw";
private String mRequestURL = "http://api.yelp.com/business_review_search?location=New%20York&ywsid=mlNrKepTs01H6gB0yoIWrw";
public static ArrayAdapter<Place> mAdapter = null;
private ListView mListView;
ArrayList<Place> arrayList = new ArrayList<Place>();
ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
if (mRequestURL == null) {
mRequestURL ="http://api.yelp.com/business_review_search?location=New%20York&ywsid=mlNrKepTs01H6gB0yoIWrw";
}
if (mAdapter==null && mRequestURL!=null) {
new DownloadFilesTask().execute(mRequestURL, null, null);
mAdapter = new Adapter(ListActivity.this, arrayList);
}
mListView = (ListView) findViewById(R.id.list);
mListView.setAdapter(mAdapter);
}
private class DownloadFilesTask extends AsyncTask<String, Void, Void> {
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(ListActivity.this);
dialog.setMessage("Please wait");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
}
protected Void doInBackground(String... urls) {
try {
arrayList = parse(mRequestURL);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ParseException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return(null);
}
@Override
protected void onPostExecute(Void places) {
dialog.dismiss();
}
}
private ArrayList<Place> parse(String u) throws IOException, ParseException {
URL url = new URL(u);
StringBuilder sb = new StringBuilder();
URLConnection yc = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String s;
while ((s=in.readLine()) != null)
sb.append(s);
in.close();
JSONParser parser = new JSONParser();
Object o = parser.parse(sb.toString());
JSONObject jsonObject1 = (JSONObject) o;
JSONArray jsonArray = (JSONArray) jsonObject1.get("businesses");
for(int i=0; i<jsonArray.size(); i++) {
JSONObject obj = (JSONObject) jsonArray.get(i);
URL photo_url = new URL((String) obj.get("photo_url"));
URL place_url = new URL((String) obj.get("url"));
String name = (String) obj.get("name");
String address = obj.get("city") + " " + obj.get("address1");
long latitude = Long.parseLong((String) obj.get("latitude"));
long longitude = Long.parseLong((String) obj.get("longitude"));
arrayList.add(new Place(photo_url, name, address, place_url, latitude, longitude));
}
File file = new File("File.txt");
ObjectOutputStream oout = new ObjectOutputStream(openFileOutput("File.txt" , 0));
oout.writeObject(arrayList);
oout.close();
return arrayList;
}
}
我的应用程序死于那个错误:
07-26 14:23:04.246: ERROR/AndroidRuntime(9262): FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1096)
Caused by: java.lang.ClassCastException: java.lang.Double
at com.example.ListActivity.parse(ListActivity.java:105)
at com.example.ListActivity.access$200(ListActivity.java:20)
at com.example.ListActivity$DownloadFilesTask.doInBackground(ListActivity.java:69)
at com.example.ListActivity$DownloadFilesTask.doInBackground(ListActivity.java:55)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
07-26 14:23:04.658: ERROR/WindowManager(9262): Activity com.example.ListActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f1be88 that was originally added here
android.view.WindowLeaked: Activity com.example.ListActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f1be88 that was originally added here
at android.view.ViewRoot.<init>(ViewRoot.java:247)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at com.example.ListActivity$DownloadFilesTask.onPreExecute(ListActivity.java:63)
at android.os.AsyncTask.execute(AsyncTask.java:391)
at com.example.ListActivity.onCreate(ListActivity.java:46)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:3)
检查latitude
和longitude
,可能是 double
而不是long
double latitude = obj.getDouble("latitude");
double longitude = obj.getDouble("longitude");
AND 在onPostExecute() method...
@Override
protected void onPostExecute(Void places) {
dialog.dismiss();
mAdapter = new Adapter(ListActivity.this, arrayList);
mListView = (ListView) findViewById(R.id.list);
mListView.setAdapter(mAdapter);
}
答案 1 :(得分:1)
您应该将mListView.setAdapter(mAdapter);
加入onPostExecute()
。
原因是doInBackground()
启动了一个在设置列表适配器时可能无法完成的新线程。 onPostExecute()
与UI线程同步,因此您可以修改GUI元素。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
mListView = (ListView) findViewById(R.id.list);
if (mRequestURL == null) {
mRequestURL ="http://api.yelp.com/business_review_search?location=New%20York&ywsid=mlNrKepTs01H6gB0yoIWrw";
}
if (mAdapter==null && mRequestURL!=null) {
new DownloadFilesTask().execute(mRequestURL, null, null);
}
}
private class DownloadFilesTask extends AsyncTask<String, Void, Void> {
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(ListActivity.this);
dialog.setMessage("Please wait");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
}
protected Void doInBackground(String... urls) {
try {
arrayList = parse(mRequestURL);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ParseException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return(null);
}
@Override
protected void onPostExecute(Void places) {
mAdapter = new Adapter(ListActivity.this, arrayList);
mListView.setAdapter(mAdapter);
dialog.dismiss();
}
}