为什么我的Android应用程序无法从JSON url获取数据?

时间:2013-11-22 02:54:21

标签: java android json textview

我正在尝试运行基于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)

5 个答案:

答案 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值

JSON Values

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)

从服务器获取数据需要执行以下步骤:

  1. 确保生成的json字符串格式正确。您可以在各个站点找到它。
  2. 从服务器请求时,您必须使用AsyncTask。
  3. 以下示例有助于理解逻辑

    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();
    }
});