使用JSON nullpointer获取值

时间:2013-08-30 16:47:42

标签: android json

我正在使用谷歌获取货币并使用json我应该得到货币的价值,但我收到一个错误。 “不幸的是,xxx已停止。”

String result = null;

我的Asynktask

private class usdjson extends AsyncTask<URL, Void, JSONObject> {

       @Override
        protected JSONObject doInBackground(URL... urls) {
               DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
               HttpPost httppost = new HttpPost("http://www.google.com/ig/calculator?hl=en&q=2GBP=?USD");
               httppost.setHeader("Content-type", "application/json");
                            InputStream inputStream = null;
                            try {
                                HttpResponse response = httpclient.execute(httppost);           
                                HttpEntity entity = response.getEntity();

                                inputStream = entity.getContent();
                                // json is UTF-8 by default
                                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                                StringBuilder sb = new StringBuilder();

                                String line = null;
                                while ((line = reader.readLine()) != null)
                                {
                                    sb.append(line + "\n");
                                }
                                result = sb.toString();
                               Log.e("Log", result);
                            } catch (Exception e) { 
                                // Oops
                            }
                            finally {
                                try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
                            }

                            JSONObject object = null;
                            try {
                                object = new JSONObject(result);
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            JSONArray Jarray = null;
                            try {
                                Jarray = object.getJSONArray("lhs");
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            JSONObject Jasonobject = null;
                            for (int i = 0; i < Jarray.length(); i++) {
                            try {
                                Jasonobject = Jarray.getJSONObject(i);
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            }
                        return Jasonobject;

        }

       @Override
        protected void onPostExecute(JSONObject jsonData) {
           value.setText(result);
        }
    }

点击我的按钮

.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            new usdjson().execute();
                            }
                    });

logcat:

08-30 21:21:51.769: E/AndroidRuntime(28903): FATAL EXCEPTION: AsyncTask #1
08-30 21:21:51.769: E/AndroidRuntime(28903): java.lang.RuntimeException: An error occured while executing doInBackground()
08-30 21:21:51.769: E/AndroidRuntime(28903):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)

3 个答案:

答案 0 :(得分:3)

使用 AsyncTask 进行网络操作,因为Android API Level-10及更高版本不支持主UI线程上的网络操作。创建Activity的子类(使其扩展AsyncTask ),然后将代码移动到子类的 doInBackground onPostExecute 方法。在 onClickListener 中使用execute方法调用子类。此外,不使用多个try catch块而是在try块上使用,并为它们编写多个catch语句。 AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html的Android文档。

setOnClickListener(new View.OnClickListener() {     
       @Override 
       public void onClick(View v) {
                new FetchData().execute(); // here FetchData is the name of the subclass
                 }
             });

FetchData类的代码是

class FetchData extends AsyncTask<String, String, String>
{
      JSONObject object = null;
      JSONArray JArray = null;
      protected String doInBackground(String...params)
       {
       try { 
        DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
                        HttpPost httppost = new HttpPost("http://www.google.com/ig/calculator?hl=en&q=2GBP=?USD");
                        httppost.setHeader("Content-type", "application/json");
        InputStream inputStream = null;
                            HttpResponse response = httpclient.execute(httppost);           
                            HttpEntity entity = response.getEntity();

                            inputStream = entity.getContent();
                            // json is UTF-8 by default 
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                            StringBuilder sb = new StringBuilder();

                             String line = null;
                            while ((line = reader.readLine()) != null)
                            { 
                                sb.append(line + "\n");
                            } 
                            result = sb.toString();
                            object = new JSONObject(result);
                            Jarray = object.getJSONArray("lhs");
                          } catch (Exception e) { 
                            e.printStackTrace();
                        } catch(JSONException e){
                            e.printStackTrace():
                         }
                       }
protected void onPostExecute(String url){
      try{
      for (int i = 0; i < Jarray.length(); i++) 
                           {
                               JSONObject Jasonobject = Jarray.getJSONObject(i);//you can access all your data using this JSONObject
                          }
    } catch(JSONException e){
      e.printStackTrace();
     }
  }
 }
}

我还认为你有一些未处理的InputStreamException,它可能导致你的应用程序崩溃。

答案 1 :(得分:1)

如Selvin所述,您正在尝试在主线程上执行网络操作,这会导致错误。 为避免这种情况,您需要在另一个线程中执行这些网络操作。

实现这一目标的最常见方法是使用扩展AsyncTask的类:http://developer.android.com/reference/android/os/AsyncTask.html

扩展AsyncTask时,您必须覆盖几种方法,特别是doInBackground()onPostExecute()。第一个将用于对后台进行网络操作,第二个将处理您将在第一个中返回的结果。

在您的情况下,网络操作在DefaultHttpClient httpclient.....之后开始,直到value.setText(result);(不包括在内)。这必须在doInBackground中完成。不要忘记返回result变量。

其余代码,实际上行value.setText(result);必须移至onPostExecute()。在那里,您将检索result并进行处理。

修改

关于你的其他问题,你应该有:

private class usdjson extends AsyncTask<URL, Void, JSONObject> {

   @Override
    protected JSONObject doInBackground(URL... urls) {

           DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
           HttpPost httppost = new HttpPost(urls[0]);
           httppost.setHeader("Content-type", "application/json");

                        InputStream inputStream = null;
                        try {
                            HttpResponse response = httpclient.execute(httppost);           
                            HttpEntity entity = response.getEntity();

                            inputStream = entity.getContent();
                            // json is UTF-8 by default
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                            StringBuilder sb = new StringBuilder();

                            String line = null;
                            while ((line = reader.readLine()) != null)
                            {
                                sb.append(line + "\n");
                            }
                            result = sb.toString();
                        } catch (Exception e) { 
                            // Oops
                        }
                        finally {
                            try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
                        }

                        JSONObject object = null;
                        try {
                            object = new JSONObject(result);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        JSONArray Jarray = null;
                        try {
                            Jarray = object.getJSONArray("lhs");
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        JSONObject Jasonobject;
                        for (int i = 0; i < Jarray.length(); i++) {
                        try {
                            Jasonobject = Jarray.getJSONObject(i);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        }
                    return Jasonobject 

    }

   @Override
    protected void onPostExecute(JSONObject jsonData) {
         value.setText(result);
    }
}

答案 2 :(得分:1)

在这种情况下,AsyncTask不是最好的方法,请尝试:

private void convert() {
    new Thread(new Runnable() {

        @Override
        public void run() {
            String url = "http://www.google.com/ig/calculator?hl=en&q="+amount+"GBP=?USD";

            String request = "THE RESULT OF YOUR HTTP REQUEST";

            try {
                JSONObject jsonObject = new JSONObject(request);

                final String result = jsonObject.getString("rhs");

                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        value.setText(result);
                    }

                });

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }

    }).start();
}