android强制关闭来自url api的json解析

时间:2013-06-05 00:31:37

标签: android json android-listview androidhttpclient

我有一个我正在构建的应用程序,它使用操作栏搜索将搜索词发送到在线api,后者发送回json结果。

到目前为止,我已经进行了搜索工作,并对json解析器进行了编码以查看结果。我还没有在列表视图中显示结果。

当我尝试使用api请求和json解析器进行搜索时,我会收到一个强制关闭。

Log Cat:

06-04 20:23:15.542: D/libEGL(31832): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
06-04 20:23:15.558: D/libEGL(31832): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
06-04 20:23:15.566: D/libEGL(31832): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
06-04 20:23:15.667: D/OpenGLRenderer(31832): Enabling debug mode 0
06-04 20:23:20.386: E/SpannableStringBuilder(31832): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-04 20:23:20.386: E/SpannableStringBuilder(31832): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-04 20:23:20.472: E/SpannableStringBuilder(31832): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-04 20:23:20.472: E/SpannableStringBuilder(31832): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-04 20:23:27.120: D/AndroidRuntime(31832): Shutting down VM
06-04 20:23:27.120: W/dalvikvm(31832): threadid=1: thread exiting with uncaught exception (group=0x4121c930)
06-04 20:23:27.144: E/AndroidRuntime(31832): FATAL EXCEPTION: main
06-04 20:23:27.144: E/AndroidRuntime(31832): android.os.NetworkOnMainThreadException
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.example.beerportfoliopro.JSONParser.getJSONFromUrl(JSONParser.java:38)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.example.beerportfoliopro.MainActivity.onQueryTextSubmit(MainActivity.java:53)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.widget.SearchView.onSubmitQuery(SearchView.java:1161)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.widget.SearchView.access$900(SearchView.java:92)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.widget.SearchView$8.onEditorAction(SearchView.java:1139)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.widget.TextView.onEditorAction(TextView.java:4117)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.android.internal.widget.EditableInputConnection.performEditorAction(EditableInputConnection.java:138)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:297)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.os.Looper.loop(Looper.java:137)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at android.app.ActivityThread.main(ActivityThread.java:5226)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at java.lang.reflect.Method.invokeNative(Native Method)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at java.lang.reflect.Method.invoke(Method.java:511)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
06-04 20:23:27.144: E/AndroidRuntime(31832):    at dalvik.system.NativeStart.main(Native Method)

API请求和JSON解析

url = url + query;
            Toast.makeText(this, url, Toast.LENGTH_SHORT).show();

            // Creating JSON Parser instance
            JSONParser jParser = new JSONParser();

            // getting JSON string from URL
            JSONObject json = jParser.getJSONFromUrl(url);

            // Getting Array of beers
            try {
                JSONArray beers = json.getJSONArray("data");

                // looping through All beers
                for(int i = 0; i < beers.length(); i++){
                    JSONObject c = beers.getJSONObject(i);

                    //get beer information
                    String beerID = c.getString("id");
                    String beerName = c.getString("name");
                    String beerDescription = c.getString("description");
                    String beerABV = c.getString("abv");
                    String beerIBU = c.getString("ibu");


                }


            } 

            catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

JSONParser.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

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;

    }
}

3 个答案:

答案 0 :(得分:2)

你应该检查printStack

android.os.NetworkOnMainThreadException

您的问题是,从Exception的名称看起来很明显,您不应该从UI Thread发出网络请求。

在android文档中查看AsyncTask

答案 1 :(得分:2)

执行至少在另一个线程上发出请求的代码。最简单的方法是使用AsyncTask。

    final String jsonUrl = url + query;
    Toast.makeText(this, jsonUrl, Toast.LENGTH_SHORT).show();

    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            // Creating JSON Parser instance
            JSONParser jParser = new JSONParser();

            // getting JSON string from URL
            JSONObject json = jParser.getJSONFromUrl(url);

            // Getting Array of beers
            try {
                JSONArray beers = json.getJSONArray("data");

                // looping through All beers
                for(int i = 0; i < beers.length(); i++){
                    JSONObject c = beers.getJSONObject(i);

                    //get beer information
                    String beerID = c.getString("id");
                    String beerName = c.getString("name");
                    String beerDescription = c.getString("description");
                    String beerABV = c.getString("abv");
                    String beerIBU = c.getString("ibu");


                }


            }

            catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }.execute();

答案 2 :(得分:0)

看起来像是StrictMode异常。您不应该在UI线程上执行任何类型的网络操作(任何操作都来自活动上下文,除非明确地放在另一个线程上),因此您需要使用Android-y之类的方法来执行此操作这,AsyncTask。

http://developer.android.com/training/articles/perf-anr.html

http://developer.android.com/reference/android/os/AsyncTask.html