【问题标题】:Async android json parser android- null pointer exception异步android json解析器android-空指针异常
【发布时间】:2013-03-29 03:46:02
【问题描述】:

从我上一篇文章中得知,我需要使用异步任务从 url 解析 json,已完成相同的操作并附在下面,

public class ReadJson extends ListActivity {
private static String url = "http://docs.blackberry.com/sampledata.json";

private static final String TAG_VTYPE = "vehicleType";
private static final String TAG_VCOLOR = "vehicleColor";
private static final String TAG_FUEL = "fuel";
private static final String TAG_TREAD = "treadType";

ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();

ListView lv ;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_read_json);
    new ProgressTask(ReadJson.this).execute();
}
private class ProgressTask extends AsyncTask<String, Void, Boolean> {
    private ProgressDialog dialog;
    // private List<Message> messages;
    public ProgressTask(ListActivity activity) {
        context = activity;
        dialog = new ProgressDialog(context);
    }
    /** progress dialog to show user that the backup is processing. */
    /** application context. */
    private Context context;
    protected void onPreExecute() {
        this.dialog.setMessage("Progress start");
        this.dialog.show();
    }
    @Override
    protected void onPostExecute(final Boolean success) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
        ListAdapter adapter = new SimpleAdapter(context, jsonlist,
                R.layout.list_item, new String[] { TAG_VTYPE, TAG_VCOLOR,
                TAG_FUEL, TAG_TREAD }, new int[] {
                R.id.vehicleType, R.id.vehicleColor, R.id.fuel,
                R.id.treadType });
        setListAdapter(adapter);
        // selecting single ListView item
        lv = getListView();
    }
    protected Boolean doInBackground(final String... args) {
        JSONParser jParser = new JSONParser();
        JSONArray json = jParser.getJSONFromUrl(url);
        for (int i = 0; i < json.length(); i++) {
            try {
                JSONObject c = json.getJSONObject(i);
                String vtype = c.getString(TAG_VTYPE);
                String vcolor = c.getString(TAG_VCOLOR);
                String vfuel = c.getString(TAG_FUEL);
                String vtread = c.getString(TAG_TREAD);
                HashMap<String, String> map = new HashMap<String, String>();
                map.put(TAG_VTYPE, vtype);
                map.put(TAG_VCOLOR, vcolor);
                map.put(TAG_FUEL, vfuel);
                map.put(TAG_TREAD, vtread);
                jsonlist.add(map);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

}

当我执行这个时,我得到空指针异常,因为在行中的 asyc 背景中执行错误,for (int i = 0; i

编辑 1:添加解析器代码

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.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

    static InputStream is = null;
    static JSONArray jarray = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    public JSONArray getJSONFromUrl(String url) {

        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = client.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }
            } else {
                Log.e("==>", "Failed to download file");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // try parse the string to a JSON object
        try {
            jarray = new JSONArray( builder.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jarray;

    }
}

【问题讨论】:

  • 您是否尝试过调试并检查数据是否解析正确?
  • 进行调试并检查JSONArray json 中是否包含值。或者执行Log.e("JSON DATA", json.toString); 并查看它是否有数据。它将显示在您的 DDMS 透视图中。
  • 我该怎么做??我不能在后台 r8 中添加 log.e 或 toast ?请建议如何检查 json 对象是否不为空
  • @bharath:阅读我之前的评论。您可以在 Runnable 块的doInBackground() 中添加Toast。只需在JSONArray json = jParser.getJSONFromUrl(url);下方添加Log.e....(如我之前的评论所示)
  • 问题出在返回 JSON 的服务器端代码中。检查任何语法或逻辑错误。在返回确认之前尝试将 json 结果打印到文件中。或者检查服务器端的错误日志文件。

标签: android json android-asynctask


【解决方案1】:

我认为您似乎正在使用this JSONParser。似乎正在发生的事情是您的 URL 没有生成有效的 JSON,这导致Exception 被抛出并在途中的某个地方被捕获 - 很可能在jObj = new JSONObject(json); 行中。最终结果是返回的变量仍然是null。因此,当您在循环中调用 json.length() 时,您是在尝试在 null 对象上调用 length()。您应该在进入循环之前对其进行检查,以确保它不是null

【讨论】:

  • 好的,我评论了 for 循环并首先检查它是否解析,然后得到这个错误,03-29 09:45:32.019: E/JSON Parser(942): Error parsing data org.json.JSONException: End of input at character 0, 检查其他示例 json 脚本,脚本很好,解析器有问题吗??
  • 更有可能是返回的数据有问题。您应该调试并从 URL 中找到实际的响应数据。
  • 从昨天开始尝试没有任何结果,是否有任何示例可以重用于使用异步解析来自 url 的元素以适用于 android 3.0 及更高版本?如果是这样,请建议,想把这个包起来!!
  • @bharath : 请显示您的 getJSONFromUrl 方法代码以获得更多帮助
  • 看看this answer如何获取URL的内容,然后你可以记录下来。之后,您应该能够查看是否有有效的 JSON 响应
【解决方案2】:

我认为,您没有从服务器获得有效的 JSON 格式。在解析之前检查从你的服务器得到的响应,这是代码的sn-p,这里传递url并获取你的ReponseInJSONStr 检查logcat中的响应字符串是否为正确的JSON格式,然后进行解析操作。

 try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(
                        url);

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            ResponseHandler<String> responseHandler = new BasicResponseHandler();

            String yourReponseInJSONStr = httpclient.execute(httppost,
                    responseHandler);

            Log.d("yourReponseInJSONStr ", yourReponseInJSONStr );

                    JSONObject yourJsonObj = new JSONObject(yourReponseInJSONStr);


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

你也可以继续解析这段代码,希望对你有帮助,

【讨论】:

    【解决方案3】:

    试试这个来获取json

    public static String getJSONString(String url) {
        String jsonString = null;
        HttpURLConnection linkConnection = null;
        try {
            URL linkurl = new URL(url);
            linkConnection = (HttpURLConnection) linkurl.openConnection();
            int responseCode = linkConnection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream linkinStream = linkConnection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int j = 0;
                while ((j = linkinStream.read()) != -1) {
                    baos.write(j);
                }
                byte[] data = baos.toByteArray();
                jsonString = new String(data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (linkConnection != null) {
                linkConnection.disconnect();
            }
        }
        return jsonString;
    }
    
    public static boolean isNetworkAvailable(Activity activity) {
        ConnectivityManager connectivity = (ConnectivityManager) activity
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity == null) {
            return false;
        } else {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    

    使用 isNetworkAvailable 检查连接

    我是这样解析的

    try {
    
                    JSONObject jObjectm = new JSONObject(result);
                    JSONObject jObject=jObjectm.getJSONObject("items");
                      if(jObject!=null)
                      {
                        Iterator<?> iterator1=jObject.keys();
                             LinkedHashMap<String,LinkedHashMap<String, Object> > inneritem = new LinkedHashMap<String, LinkedHashMap<String, Object> >();
                            while (iterator1.hasNext() ){
                                Item hashitem=new Item();
                                   String key1 = (String)iterator1.next();
                                   JSONObject jObject1=jObject.getJSONObject(key1);
                                   Iterator<?> iterator=jObject1.keys();
                                     LinkedHashMap<String, Object> inneritem1 = new LinkedHashMap<String, Object>();
                                    while (iterator.hasNext() ){
    
    
                                        String key =(String) iterator.next();
    
                                      inneritem1.put(key, jObject1.get(key));
    
    
                                    }
                                     hashitem.setItem(key1,inneritem1);
                                    inneritem.put(key1,inneritem1);
                                    arrayOfList.add(hashitem); 
                            }
    
    
    
    
                      }
                    } catch (JSONException e) {
    
                        System.out.println("NO Json data found");
                    }
    

    【讨论】:

    • 这会将整个内容作为字符串提供吗?
    • 是的..只需将该字符串传递给 JSONOBJECT 并根据您的需要进行解析
    猜你喜欢
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多