繁体   English   中英

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

[英]Why my android app cannot get data from JSON url?

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

更新:

android:minSdkVersion =“ 8”

android: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)

发生问题是因为您试图在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 BA below B ,然后B below A A below BA below B引起问题!

您可以使用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));

    }
}));

我使用了Kevin Sawicki的HTTP请求库 ,它非常有用,请在下面找到工作示例。 不要忘记添加android权限

<uses-permission android:name="android.permission.INTERNET" />

http://api.worldbank.org/countries/ir?format=json检索到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);
    }

 }
}

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

  1. 确保您生成的json字符串格式正确。您可以在各种网站上找到它。
  2. 从服务器请求时,您必须使用AsyncTask。

以下示例可能有助于理解逻辑

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;

}

我的猜测是,这是因为您正在尝试在主线程上进行网络活动。 那是不可以的。

也许在其中添加默认异常处理程序和断点会有所帮助-

Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        throwable.printStackTrace();
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM