我正在尝试运行基于WorlBank API的应用。我有一个JSON URL来获取有关某个国家/地区的数据,然后在TextViews中显示它。简单。但只要我在关闭时运行应用程序。
以下是我的文件:
主要活动:
public class MainActivity extends Activity {
//URL to get JSON Array
private static String url = "http://api.worldbank.org/countries/ir?format=json";
//JSON node Names
private static final String PAGE = "page";
private static final String VALUE = "value";
private static final String NAME = "name";
private static final String GEO = "region";
JSONArray page = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
try{
//Getting JSON Array
page = json.getJSONArray(PAGE);
JSONObject c = page.getJSONObject(0);
//Sorting JSON item in a Variable
String value = c.getString(VALUE);
String name = c.getString(NAME);
String geo = c.getString(GEO);
//Importing to TextView
final TextView id1 = (TextView) findViewById(R.id.id);
final TextView name1 = (TextView) findViewById(R.id.name);
final TextView geo1 = (TextView) findViewById(R.id.geo);
//set JSON Data in TextView
id1.setText(value);
name1.setText(name);
geo1.setText(geo);
} catch (JSONException e){
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
JSONParser:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
XML:
<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/id"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/geo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/id"
android:layout_alignParentTop="true"
android:layout_marginTop="76dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
有什么想法吗?
世界银行api:http://data.worldbank.org/node/18
更新:
机器人:的minSdkVersion = “8”
机器人:targetSdkVersion = “18”
FATAL EXCEPTION: main
E/AndroidRuntime(966): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.jsonsyctask/com.example.jsonsyctask.Main}: android.os.NetworkOnMainThreadException
E/AndroidRuntime(966): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
E/AndroidRuntime(966): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
E/AndroidRuntime(966): at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime(966): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
E/AndroidRuntime(966): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(966): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(966): at android.app.ActivityThread.main(ActivityThread.java:5103)
E/AndroidRuntime(966): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(966): at java.lang.reflect.Method.invoke(Method.java:525)
E/AndroidRuntime(966): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
答案 0 :(得分:5)
问题正在发生,因为您正在尝试在UI线程上执行网络操作。您需要使用后台线程进行网络操作。
使用AsyncTask
,如下所示:
public class MainActivity extends Activity {
//URL to get JSON Array
private static String url = "http://api.worldbank.org/countries/ir?format=json";
//JSON node Names
private static final String PAGE = "page";
private static final String VALUE = "value";
private static final String NAME = "name";
private static final String GEO = "region";
JSONArray page = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetJSONTask().execute(url);
// do not parse here..
...
...
}
...
...
class GetJSONTask extends AsyncTask<String, Void, JSONObject> {
protected JSONObject doInBackground(String... urls) {
try {
JSONParser jParser = new JSONParser();
return jParser.getJSONFromUrl(urls[0]);
} catch (Exception e) {
return null;
}
}
protected void onPostExecute(JSONObject json) {
// do all the parsing here:
try {
//Getting JSON Array
page = json.getJSONArray(PAGE);
JSONObject c = page.getJSONObject(0);
//Sorting JSON item in a Variable
String value = c.getString(VALUE);
String name = c.getString(NAME);
String geo = c.getString(GEO);
//Importing to TextView
final TextView id1 = (TextView) findViewById(R.id.id);
final TextView name1 = (TextView) findViewById(R.id.name);
final TextView geo1 = (TextView) findViewById(R.id.geo);
//set JSON Data in TextView
id1.setText(value);
name1.setText(name);
geo1.setText(geo);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
}
参考:http://developer.android.com/reference/android/os/AsyncTask.html
更新发现另一个错误,更新XML
<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
...
...
您不能拥有两个观点并说A below B
,然后B below A
cause problems!
答案 1 :(得分:0)
您可以使用droidQuery:
大大简化您正在执行的所有操作$.ajax(new AjaxOptions().url(url).success(new Function() {
@Override
public void invoke($ d, Object... args) {
JSONObject json = (JSONObject) args[0];
JSONArray page = json.getJSONArray(PAGE);
JSONObject c = page.getJSONObject(0);
$.with(MyActivity.this, R.id.id).text(c.getString(VALUE))
.id(R.id.name).text(c.getString(NAME))
.id(geo).text(c.getString(GEO));
}
}));
答案 2 :(得分:0)
我使用Kevin Sawicki的HTTP Request Library非常有帮助,找到下面的工作示例。别忘了添加Android权限
<uses-permission android:name="android.permission.INTERNET" />
从http://api.worldbank.org/countries/ir?format=json
中检索json值
package com.javasrilankansupport.testhttps;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.github.kevinsawicki.http.HttpRequest;
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadTask().execute("http://api.worldbank.org/countries/ir?format=json");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class DownloadTask extends AsyncTask<String, Long, Boolean> {
protected Boolean doInBackground(String... urls) {
try {
// kevinsawicki's HttpRequest from github
HttpRequest request = HttpRequest.get(urls[0])
.trustAllCerts() // for HTTPS request
.trustAllHosts() // to trust all hosts
.acceptJson(); // to accept JSON objects
if (request.ok()) {
JSONObject jsonObject;
try {
String s = request.body();
Log.d("MyApp",
"Downloaded json data: "+ s);
// change parameters according to your JSON
jsonObject = new JSONObject(s);
JSONArray jsonArray = jsonObject
.getJSONArray("categories");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObj = jsonArray.getJSONObject(i);
Log.d("MyApp",
"Downloaded json data: "
+ jsonObj.getString("id") + " "
+ jsonObj.getString("slug"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
System.out.print("error");
}
} catch (HttpRequestException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onProgressUpdate(Long... progress) {
// progress bar here
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
}
}
}
答案 3 :(得分:0)
从服务器获取数据需要执行以下步骤:
以下示例有助于理解逻辑
package com.example.sonasys.net;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.sonaprintersd.R;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
public class SingleContactActivity extends Activity {
private static final String TAG_CONTACTS = "Contacts";
private static final String TAG_POSTLINE = "PostLine";
private static final String TAG_Post_Img = "Post_Img";
private static final String TAG_Post_Img_O = "Post_Img_O";
private static String url;
TextView uid, pid;
JSONArray contacts = null;
private ProgressDialog pDialog;
String details;
// String imagepath = "http://test2.sonasys.net/Content/WallPost/b3.jpg";
String imagepath = "";
Bitmap bitmap;
ImageView image;
String imagepath2;
ArrayList<HashMap<String, String>> contactList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_contact);
url = "http://test2.sonasys.net/MobileApp/GetSinglePost?UserId="
+ uid.getText() + "&Post_ID=" + pid.getText();
contactList = new ArrayList<HashMap<String, String>>();
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(SingleContactActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
// pDialog.setTitle("Post Details");
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
JSONObject c = contacts.getJSONObject(0);
details = c.getString(TAG_POSTLINE);
imagepath = c.getString(TAG_Post_Img);
imagepath2 = c.getString(TAG_Post_Img_O);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**/
TextView Details = (TextView) findViewById(R.id.details);
// Details.setText(details);
Details.setText(android.text.Html.fromHtml(details));
}
}
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/*
* Making service call
* @url - url to make request
* @method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/*
* Making service call
* @url - url to make request
* @method - http request method
* @params - http request params
*
* */
public String makeServiceCall(String url, int method,List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
答案 4 :(得分:-2)
我的猜测是,这是因为您正在主线程上尝试网络活动。这是禁忌。
也许在那里添加一个默认的异常处理程序和一个断点 -
Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
throwable.printStackTrace();
}
});