专栏首页风吹杨柳json字符串解析问题---有网和无网的情况下都要给用户友好的体验问题

json字符串解析问题---有网和无网的情况下都要给用户友好的体验问题

最近遇到这样的问题,就是加了  网络检查  但是如果当前的app在运行的时候没有退出,同时这个时候断网了,如果再请求,我忘记了再次去检查网络,如果加了网络检查就不需要看下面的东西,如果没有加网络检查的话,那么就出现下面的bug

首先程序跟踪是   :

11-03 13:30:30.134: E/AndroidRuntime(26947): java.lang.NullPointerException
11-03 13:30:30.134: E/AndroidRuntime(26947): 	at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
11-03 13:30:30.134: E/AndroidRuntime(26947): 	at org.json.JSONTokener.nextValue(JSONTokener.java:94)
11-03 13:30:30.134: E/AndroidRuntime(26947): 	at org.json.JSONObject.<init>(JSONObject.java:155)
11-03 13:30:30.134: E/AndroidRuntime(26947): 	at org.json.JSONObject.<init>(JSONObject.java:172)

上面的问题我相信大家经常碰见,就是没有网的时候服务器上返回的数据为空,json解析的时候自然就会报这样的错,而且是直接弹出   

当前程序已停止运行

现在首先说下我的网络访问---json解析---在返回给handler处理的机制:

网络访问应该大家都是一样的,就是一个post请求  get这样就不说了:

</pre><pre name="code" class="java">	private static HttpClient client = new DefaultHttpClient();

	public String getJsonString(String url) {
		String result = "";
		String line = "";
		InputStream is = null;
		try {
			HttpClient httpclient = new DefaultHttpClient();
			httpclient.getParams().setParameter(
					CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
			httpclient.getParams().setParameter(
					CoreConnectionPNames.SO_TIMEOUT, 5000);
			HttpResponse response = httpclient.execute(new HttpGet(url));
			is = response.getEntity().getContent();
			if (is != null) {
				BufferedReader rd = new BufferedReader(
						new InputStreamReader(is));
				while ((line = rd.readLine()) != null) {
					result += line;
				}
				is.close();
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String doPost(String url, ArrayList<BasicNameValuePair> data) {

		try {
			// UrlEncodedFormEntity这个类是用来把输入数据编码成合适的内容
			// 两个键值对,被UrlEncodedFormEntity实例编码后变为如下内容:param1=value1¶m2=value2
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(data,HTTP.UTF_8);// 首先将参数设置为utf-8的形式,
			String result = "";// 向服务器请求之后返回的数据结果
			HttpClient httpClient = new DefaultHttpClient();// 申明一个网络访问客户端
			HttpPost post = new HttpPost(url);// post方式
			post.setEntity(entity);// 带上参数
			HttpResponse httpResponse = httpClient.execute(post);// 响应结果
			if (httpResponse.getStatusLine().getStatusCode() == 200) {// 如果是200 表示成功
				result = EntityUtils.toString(httpResponse.getEntity());// 把结果取出来 是一个STRING类型的
			}
			return result;
		} catch (Exception e) {
			return null;
		}
	}

把上面的代码放到一个工具类里面   要做的时候自己调用就行

现在就是访问有两种写法:

一种是直接调用上面的方法,得到返回的数据,再专门做一个json解析的工具类   推荐这种方法,避免很多错误

第二种是直接写个方法,在方法里面调用上面的请求代码,返回直接把json解析也在这里面做了,直接把需要的结果给程序就行,这样在handler里面避免很多业务处理,

比如我们需要判断状态,根据状态做不同的事,如果你的目的明确,减少程序里面各种代码,这种方法也是可以的,但是就是好多  空指针的错误会般绕着你啊

我的错误就是出现在第二种方法里面,没有网的时候,报 空指针错误,这种错误会直接让当前的 程序停止运行,必须要处理掉

下面的代码里面有注释,避免空指针错误  

	public static ArrayList<Object> getBigProjectInfoData(String URL, ArrayList<BasicNameValuePair> data) {
		ArrayList<Object> list = new ArrayList<Object>();//返回结果自己定义的,很多时候是返回ArrayList 有的时候返回map更方便,看自己的需要把
		HttpTools httptools = new HttpTools();
		String result = httptools.doPost(URL, data);
		if(result == null){
			//这里的代码是必须要的,避免空指针错误,否则程序直接退出,
			return null;
		}
		
		if{
			try {
				//解析json数据 涉及到多层解析json我这里就不写了,其实网上有工具能够解析到三层,
				//我一直要求后台返回的json不要超过3层,越多解析起来越麻烦,

			} catch (JSONException e) {
			}
			return list;
		}	
		
	}

接下来说第一种方法,第一种方法就是把网络访问和json解析分离了,我推荐大家使用这种,

你必须自己再写一个json解析工具,因为调用异步进程请求网络的时候返回的就是一个json字符串,string类型的

下面是异步线程的代码:

		new Thread(new Runnable() {
			@SuppressWarnings("deprecation")
			@Override
			public void run() {
				Message msg = Message.obtain();
				ArrayList<BasicNameValuePair> data = new ArrayList<BasicNameValuePair>();//用于post请求的键值对,前面的参数是键,后面的是值
				if(netCheck.isNetworkConnected() == true){//如果有网,就执行网络请求,如果没有网就不做网络请求
					msg.obj = HttpTools.doPost(Constants.URL_ALL_MYWORKER_INFO,data);//调用URL  获取数据集
					msg.what = INIT;//给handler传回的类型
				}else{
					msg.obj = "network is failed";
					msg.what = NOTNETWORK;
				}
				getDateHandler.sendMessage(msg);//执行传递
			}
		}).start();	

其实这里面已经加上了检查网络的情况:

然后把服务器返回的东西交给handler处理,这个时候有人肯定说  你这种情况也有可能是返回null啊,只要你保证后台每次网络请求不管是失败还是成功,都返回状态码就可以避免空指针的问题

在handler里面你不是处理msg.obj了吗,然后交给专业的解析工具处理,或者是自己写处理工具都行

下面的代码是自己写处理json

	public ArrayList<TiebaModule> getTiebaModule(String jsonStr)
	{
		try
		{
			ArrayList<TiebaModule> result = new ArrayList<TiebaModule>();
			JSONArray jArray = new JSONArray(jsonStr);
			JSONObject jsonObj;
			for(int i = 0; i < jArray.length() ; i++)
			{
				TiebaModule module = new TiebaModule();
				jsonObj = jArray.getJSONObject(i);
				module.setModuleId(jsonObj.optString("moduleid"));//
				module.setModuleImg(jsonObj.optString("moduleimg"));//
				module.setModuleName(jsonObj.optString("modulename"));//
				result.add(module);
			}
			return result;
		}
		catch(Exception e)
		{
			return null;
		}
	}

这里面换成了如果遇到  空指针 或者其他的异常情况,直接返回null

其实说这么多  关键的地方就是  空指针导致  程序直接停止运行了,只要你把这个异常捕捉到就行,

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实习杂记(31):android多dex方案一

    内部复杂创造的方法是:return new PathClassLoader(classPath, BootClassLoader.getInstance());

    wust小吴
  • SVN安装---本机安装(1)

    wust小吴
  • ViewPager显示不完整的解决办法

    找了好久,发现解决办法超级简单,不需要去重写自定义的ViewPageAdapter里面的什么getView方法,重新根据子视图来设定大小

    wust小吴
  • python的unittest模块

    unittest库提供了test cases, test suites, test fixtures,test runner。

    于小勇
  • Linux-mknod命令(9)

    mknod命令用于创建字符设备文件和块设备文件 (ls /dev -l 结果显示b开头和c开头的,即标识了块设备和字符设备。) 为了管理设备,所以设备中都有两个...

    张诺谦
  • 动画演示 floodfill 算法填充颜色

    上次我们谈到如何使用深度优先搜索解决迷宫问题。这次,我们再来看看深度优先搜索的其他应用,来模仿 photoshop 的魔棒功能来填充颜色。使用扫描线填充算法(s...

    用户2870857
  • JDK1.9-模拟斗地主洗牌发牌

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    cwl_java
  • SSH + Google Authenticator 安全加固

    Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实...

    惨绿少年
  • 超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本

    上一篇自动化测试,全面且详细的介绍了从零开始到发布版本的步骤,这是传统的方式,本次为大家带来的是如何在5分钟内使用上docker进行CI/CD,毕竟现在的容器化...

    梁规晓
  • Nginx主要功能及使用

    反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理(Reverse Proxy)方式是指以代理服务器来接受 int...

    用户1149268

扫码关注云+社区

领取腾讯云代金券