2016-03-26 3 views
0

Asyncクラスでnullポインタ例外が発生する理由を説明してください。 URLからデータを取得しようとしていますが、次のコードを含む162のnullポインタ例外が発生します。AsyncクラスのURLからJSONデータを解析しようとしたときにnullポインタ例外が発生する

int lengthJsonArr = jsonMainNode.length();

私はそれがなぜであるかはわかりませんが、誰かがそれが偉大なものになるのを助けることができたら。誰かが私にURLからのjsonデータを取得するためのより良い選択肢を示してくれれば、それは大きな助けにもなります。

public class userTask extends AsyncTask<String, Void, Void>{ 
    HttpURLConnection connection = null; 
    private String Content; 
    @Override 
    protected Void doInBackground(String... urls) { 

     BufferedReader reader = null; 
     try { 
      URL url = new URL(urls[0]); 
      connection = (HttpURLConnection) url.openConnection(); 
      connection.connect(); 

      InputStream stream = connection.getInputStream(); 

      reader = new BufferedReader(new InputStreamReader(stream)); 

      StringBuffer buffer = new StringBuffer(); 

      String line = ""; 
      while ((line = reader.readLine()) != null) { 
       buffer.append(line); 
      } Content = buffer.toString(); 


     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (connection != null) { 
       connection.disconnect(); 
      } 
      try { 
       if (reader != null) { 
        reader.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void s) { 
     super.onPostExecute(s); 

     String OutputData = ""; 
     JSONObject jsonResponse; 

     try { 
      jsonResponse = new JSONObject(Content); 
      JSONArray jsonMainNode = jsonResponse.optJSONArray("Android"); 

      int lengthJsonArr = jsonMainNode.length(); //This is causing the exception 

      for (int i =0; i < lengthJsonArr; i++) { 
       JSONObject jsonChildNode = jsonMainNode.getJSONObject(i); 
       String name = jsonChildNode.optString("name").toString(); 
       Double longitude = jsonChildNode.optDouble("lon"); 
       Double latitude = jsonChildNode.optDouble("lat"); 

       OutputData += " Name : "+ name +" " 
         + "Longitude : "+ longitude +" " 
         + "Latitude : "+ latitude +" " 
         +"-------------------------------------------------- "; 

       //Show Parsed Output on screen (activity) 
       Toast toast = Toast.makeText(getApplicationContext(), OutputData, Toast.LENGTH_LONG); 
       toast.show(); 


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

'Content'はAsyncTaskのインスタンス変数です。あなたはdoInBackgroundからそれを返し、onPostExecuteでそれを操作する必要があります。 –

+0

"URLからjsonデータを取得するためのより良い代替方法" - VolleyまたはOkHttpライブラリは素晴らしい選択肢ですが、あなたのnull値を取得しているという事実は解決しませんAndroid配列のJSONオブジェクト。 –

+0

doInBackground()はStringコンテンツを返す必要があり、onPostExecutはその文字列をinput(parameter)として受け取る必要があります。したがって、AsyncTask として修正する必要があります。 – GVillani82

答えて

1

これは、AndroidでJSONデータを取得するのには適していません。 VolleyまたはRetrofitライブラリを使用する必要があります。これらのライブラリは、通常のコードよりも正確かつ効率的に動作します。

データを取得する際には、大事なことがあります。すべては図書館で行われます。そして、コードの数行を書くだけでいいです。

Googleで多くの良いチュートリアルに従うことができます。

+0

私はそれらの図書館を調べようとしていますが、あなたに素晴らしいことを説明するリンクを私に提供できるのであれば、まともなチュートリアルを見つけることができません。 – user6020197

+0

あなたはこのリンク[volley](http://developer.android.com/training/volley/index.html)で詳細な情報を見つけることができます。このリンクでは、ボレーに関する素晴らしいビデオを見つけることができます。幸運 – Kathi

+0

あなたはこのリンクに従うことができます:このリンクのhttps://www.youtube.com/watch?v=FzwBYPzCIHk RequestQueueは通常のクラスで作成されます。 Singletonクラスを使用してRequestQueueオブジェクトを作成することをお勧めします。 Bczそれは高価です。 –

0

、この作品のよう...

jsonResponse = new JSONObject(Content); 

...あなたは、少なくとも正常に有効なJSONオブジェクトを含むHTTPレスポンスを受信します。

次の行...

JSONArray jsonMainNode = jsonResponse.optJSONArray("Android"); 

は... JSON配列を抽出しようとしますが、明らかに失敗し、結果としてあなたjsonMainNode変数がnullです。それがoptJSONArray()の仕組みです。求められたものが見つからない場合は、nullを返します。あなたはヌル JSON配列の長さを得ることができないので、(代わりに例えばJSONExceptionを投げる。)

その後、次の行が...もちろん

int lengthJsonArr = jsonMainNode.length(); 

...は失敗します。

これは、受け取ったJSONに「Android」という配列が含まれていないようです。あなたはブレークポイントを置くことができますか?...

JSONArray jsonMainNode = jsonResponse.optJSONArray("Android"); 

...そしてJSONオブジェクトの内容を確認してください。または、応答を印刷するだけです。 (人々は、Javaコーディング規約についてガミガミしないように、適切に小文字で「コンテンツ」という名前を付けます...)

あなたのようなコードを使用することができNullPointerExceptionを回避するためとして:しないでください

if (jsonResponse.has("Android")) { 
    JSONArray jsonMainNode = jsonResponse.optJSONArray("Android"); 
    int lengthJsonArr = jsonMainNode.length(); 
    // Etc. 
    // ... 
} 
else { 
    // TODO: Recover from the situation. 
    // ... 

} 
関連する問題