解析JSON数据,并从其中的图片地址取图片
2015-08-12 21:22
1326 查看
首先,要解决的是取JSON对象,JSON对象里面还嵌套了3个JSON对象,然后其中一个JSON对象又嵌套了一个JSON对象和数组,如下格式的:
下面开始解析,首先联网取得JSON数据,但是需要在异步线程(AsyncTask)里面去联网取数据,否则涉及到阻塞的问题,然后在异步线程的onPostExecute()方法里面去处理,注意的是,异步线程中只有doInBackground()方法是后台操作的,其他方法都是主线程执行的,还需要一个Bean类对象去添加和取我们解析出来的具体数据,我用的android自带的JSON解析的,一步一步去解析:
下面是工具类,除了图片缓存那一块,其他的现在我也看不懂,源码找便,有些方法都没看懂,就是有些单行代码还可以看但是串起来就不晓得是啥了:
运行,你会发现就一开加载的会慢点,但你重新滑回去的时候,图片就不会在去加载:
其中主要的地方就是去一步一步的解析出我们的数组:
下面开始解析,首先联网取得JSON数据,但是需要在异步线程(AsyncTask)里面去联网取数据,否则涉及到阻塞的问题,然后在异步线程的onPostExecute()方法里面去处理,注意的是,异步线程中只有doInBackground()方法是后台操作的,其他方法都是主线程执行的,还需要一个Bean类对象去添加和取我们解析出来的具体数据,我用的android自带的JSON解析的,一步一步去解析:
public class ListViewJsonActivity extends Activity { private ListView mListViewJsonData; //开启多线程的那个类 private Executor mExcutor; //这个集合装我们的Bean数据,就是解析出来的那个数组里面的内容 private ArrayList<ListViewBeanJson> listJSONObject = new ArrayList<ListViewBeanJson>(); //自己定义的一个适配器 private ListViewAdapterGotHttp mAdapter; //声明工具类 private ToolClassStorBitmap mToolClassStorBitmap; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_listview_json_layout); // ThreadPoolExecutor这个是开启多线程的一个类,构造方法解释: //(一次只能开启10个线程运行,一共可以容纳100个线程在里面,每个线程运行的时间为10秒钟,后面2个不晓得啥意思,照着敲就行); mExcutor = new ThreadPoolExecutor(10, 100, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()); //封装的一个工具类,就是他们说的框架啥的,意思就是第一次接触框架了 mToolClassStorBitmap = ToolClassStorBitmap.getIntance(); //开启工具类里面的多线程运行取图片和数据; mToolClassStorBitmap.startMoreThread(); //为了防止上下滑动时。图片会变和错位,采用了缓存android提供的LruCache mToolClassStorBitmap.getBitmapStorageSpace(); mAdapter = new ListViewAdapterGotHttp(this); mListViewJsonData = (ListView) findViewById(R.id.json_listview_for_http); getHttpData(urlAddress); } /** * 启动多个线程取取JSON对象 */ public void getHttpData(String url) { new AsyncTask<String, Void, String>() { protected String doInBackground(String... params) { String str = httpGetMesg(params[0]); return str; } protected void onPostExecute(String result) { try { // 先获得整体的JSON对象 JSONObject jsonObkect = new JSONObject(result); // 从整体的JSON对象中此处获得info的JSON对象 JSONObject jsonInfo = jsonObkect.getJSONObject("info"); // 再从info对象中获得我们的JSON数组对象merchantKey,这就是我们最终需要的数据来源数组 JSONArray jsonMerchantKey = jsonInfo .getJSONArray("merchantKey"); // 这儿就可以用我们的循环遍历方法去操作我们的数组了 int n = jsonMerchantKey.length(); for (int i = 0; i < n; i++) { //获得数组里面的具体对象,然后从他们里面抽取我们需要的数据 JSONObject jsonArrayDat = jsonMerchantKey .getJSONObject(i); ListViewBeanJson beanJson = new ListViewBeanJson(); beanJson.setShopImg(jsonArrayDat.getString("picUrl")); beanJson.setCardShopImg(jsonArrayDat .getString("cardType")); beanJson.setGroupShopImg(jsonArrayDat .getString("groupType")); beanJson.setCouponShopImg(jsonArrayDat .getString("couponType")); beanJson.setShopNameText(jsonArrayDat.getString("name")); beanJson.setShopMessageText(jsonArrayDat .getString("coupon")); beanJson.setShopAddressText(jsonArrayDat .getString("location")); beanJson.setShopMapText(jsonArrayDat .getString("distance")); listJSONObject.add(beanJson); } mAdapter.setData(listJSONObject); mListViewJsonData.setAdapter(mAdapter); } catch (JSONException e) { e.printStackTrace(); } } }.executeOnExecutor(mExcutor, url); } /** * 网络获取JSON对象 */ public String httpGetMesg(String urls) { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(urls); HttpResponse response = httpClient.execute(httpGet); int n = response.getStatusLine().getStatusCode(); if (n == HttpStatus.SC_OK) { String line = EntityUtils.toString(response.getEntity(), "UTF-8"); return line; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 自定义适配器,并添加数据到布局 */ public class ListViewAdapterGotHttp extends BaseAdapter { private LayoutInflater infalter; private ArrayList<ListViewBeanJson> listJSONAdapter = new ArrayList<ListViewBeanJson>(); public ListViewAdapterGotHttp(Context context) { infalter = LayoutInflater.from(context); } public void setData(ArrayList<ListViewBeanJson> listJSONObjects) { listJSONAdapter = listJSONObjects; notifyDataSetChanged(); } public int getCount() { return listJSONAdapter.size(); } public Object getItem(int position) { return listJSONAdapter.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { final ListViewBeanJsonReasou mListViewBeanJson; if (convertView == null) { convertView = infalter.inflate( R.layout.listview_item_jsondata_layout, null); mListViewBeanJson = new ListViewBeanJsonReasou(); mListViewBeanJson.shopImg = (ImageView) convertView .findViewById(R.id.listview_json__shopimg); mListViewBeanJson.groupShopImg = (ImageView) convertView .findViewById(R.id.listview_json__groupshopping); mListViewBeanJson.couponShopImg = (ImageView) convertView .findViewById(R.id.listview_json__coupon); mListViewBeanJson.cardShopImg = (ImageView) convertView .findViewById(R.id.listview_json__shoppingcard); mListViewBeanJson.ShopNameText = (TextView) convertView .findViewById(R.id.listview_json_shopname); mListViewBeanJson.ShopMessageText = (TextView) convertView .findViewById(R.id.listview_json_shopmessage); mListViewBeanJson.ShopAddressText = (TextView) convertView .findViewById(R.id.listview_json_shopaddress); mListViewBeanJson.ShopMapText = (TextView) convertView .findViewById(R.id.listview_json_shopmap); convertView.setTag(mListViewBeanJson); } else { mListViewBeanJson = (ListViewBeanJsonReasou) convertView .getTag(); } ListViewBeanJson jsonDataBean = (ListViewBeanJson) getItem(position); mListViewBeanJson.ShopNameText.setText(jsonDataBean .getShopNameText()); mListViewBeanJson.ShopMessageText.setText(jsonDataBean .getShopMessageText()); mListViewBeanJson.ShopAddressText.setText(jsonDataBean .getShopAddressText()); mListViewBeanJson.ShopMapText .setText(jsonDataBean.getShopMapText()); if (jsonDataBean.getGroupShopImg().equals("YES")) { mListViewBeanJson.groupShopImg .setImageResource(R.drawable.near_group); } if (jsonDataBean.getCouponShopImg().equals("YES")) { mListViewBeanJson.couponShopImg .setImageResource(R.drawable.near_ticket); } if (jsonDataBean.getCardShopImg().equals("YES")) { mListViewBeanJson.cardShopImg .setImageResource(R.drawable.near_card); } //从Bean类里面获取图片的地址 String ms = jsonDataBean.getShopImg(); mToolClassStorBitmap.loadBitmap(getResources(), ms, mListViewBeanJson.shopImg, R.drawable.m3); return convertView; } } class ListViewBeanJsonReasou { private ImageView shopImg; private ImageView groupShopImg; private ImageView couponShopImg; private ImageView cardShopImg; privat 4000 e TextView ShopNameText; private TextView ShopMessageText; private TextView ShopAddressText; private TextView ShopMapText; } }
下面是工具类,除了图片缓存那一块,其他的现在我也看不懂,源码找便,有些方法都没看懂,就是有些单行代码还可以看但是串起来就不晓得是啥了:
/** * 封装了网络取图片,缓存,上下滑动时,图片错位的问题 * * @author Administrator * */ public class ToolClassStorBitmap { private Executor mExcutor; private LruCache<String, Bitmap> mLruCache; public static ToolClassStorBitmap mToolClassStorBitmap = null; /** 单例模式 */ public static ToolClassStorBitmap getIntance() { if (mToolClassStorBitmap == null) { mToolClassStorBitmap = new ToolClassStorBitmap(); } return mToolClassStorBitmap; } /** * 设置多线程取图片 */ public void startMoreThread() { mExcutor = new ThreadPoolExecutor(10, 100, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()); } /** * LruCache:在程序内存达到设定值时会将最少最近使用的图片移除掉。 先获取存储器最大内存, 再取6分之1来存储图片 */ public void getBitmapStorageSpace() { // 获取应用程序最大应用内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); // 只需要其最大内存的8分之1 int cacheSize = maxMemory / 8; mLruCache = new LruCache<String, Bitmap>(cacheSize) { protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; } /** * 将图片存储到LruCache 采用键值对进行添加,先判断内存是否存在此地址, */ public void storeBitmapToMemory(String mapKey, Bitmap map) { if (getBitmapToMemory(mapKey) == null) { mLruCache.put(mapKey, map); } } /** * 从存储区域去取图片 * */ public Bitmap getBitmapToMemory(String mapKey) { return mLruCache.get(mapKey); } /** * 网络获得图片 */ public Bitmap getBitmapForHttp(String httpUrl) { InputStream input = null; try { URL url = new URL(httpUrl); input = url.openStream(); Bitmap map = BitmapFactory.decodeStream(input); return map; } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (input != null) { try { input.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } public void loadBitmap(Resources rea, String imageUrl, ImageView imageView, int resImgID) { // 先判断内存里面是否有这张图片,有就直接放上去,然后结束掉,没有就执行下面的 Bitmap mapToLruCache = getBitmapToMemory(imageUrl); if (mapToLruCache != null) { imageView.setImageBitmap(mapToLruCache); return; } if (cancelPotentialWork(imageUrl, imageView)) { BitmapWorkerTask task = new BitmapWorkerTask(imageView); AsyncDrawable asyncDrawable = new AsyncDrawable(rea, BitmapFactory.decodeResource(rea, resImgID), task); imageView.setImageDrawable(asyncDrawable); if (mExcutor == null) { task.execute(imageUrl); } else { task.executeOnExecutor(mExcutor, imageUrl); } } } public static boolean cancelPotentialWork(String imageUrl, ImageView imageView) { final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (bitmapWorkerTask != null) { final String bitmapData = bitmapWorkerTask.data; //判断2个地址是否相同,即图片是否存在 if (!bitmapData.equals(imageUrl)) { // Cancel previous task bitmapWorkerTask.cancel(true); } else { // The same work is already in progress return false; } } // No task associated with the ImageView, or an existing task was // cancelled return true; } private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { if (imageView != null) { final Drawable drawable = imageView.getDrawable(); //这if里面都啥写法,没见过。。。。。。。。。。。。。。。 if (drawable instanceof AsyncDrawable) { final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; return asyncDrawable.getBitmapWorkerTask(); } } return null; } /** * 创建一个专用的Drawable的子类来储存返回工作任务的引用。在这种情况下,当任务完成时BitmapDrawable会被使用 * */ static class AsyncDrawable extends BitmapDrawable { private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>( bitmapWorkerTask); } public BitmapWorkerTask getBitmapWorkerTask() { return (BitmapWorkerTask) bitmapWorkerTaskReference.get(); } } //先建一个类,继承我们的异步线程任务,返回BitmapWorkerTask对象,不晓得这个对象干啥用的 class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; private String data = ""; public BitmapWorkerTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage // collected imageViewReference = new WeakReference<ImageView>(imageView); } // Decode image in background. @Override protected Bitmap doInBackground(String... params) { data = params[0]; //网络取图片,并返回 return getBitmapForHttp(data); } // Once complete, see if ImageView is still around and set bitmap. @Override protected void onPostExecute(Bitmap bitmap) { if (isCancelled()) { bitmap = null; } if (imageViewReference != null && bitmap != null) { final ImageView imageView = (ImageView) imageViewReference .get(); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (this == bitmapWorkerTask && imageView != null) { imageView.setImageBitmap(bitmap); // 内存没有这张图片,就添加进去 storeBitmapToMemory(data, bitmap); } } } } }
运行,你会发现就一开加载的会慢点,但你重新滑回去的时候,图片就不会在去加载:
其中主要的地方就是去一步一步的解析出我们的数组:
protected void onPostExecute(String result) { try { // 先获得整体的JSON对象 JSONObject jsonObkect = new JSONObject(result); // 从整体的JSON对象中此处获得info的JSON对象 JSONObject jsonInfo = jsonObkect.getJSONObject("info"); // 再从info对象中获得我们的JSON数组对象merchantKey,这就是我们最终需要的数据来源数组 JSONArray jsonMerchantKey = jsonInfo .getJSONArray("merchantKey"); // 这儿就可以用我们的循环遍历方法去操作我们的数组了
相关文章推荐
- Js实现排序算法
- The JavaScript Event Loop: Explained
- jsoup html
- jstree动态生成树
- JS学习十一天----类和模块
- JSP学习笔记(五):web.xml中的url-pattern的映射规则
- JavaScript基础学习之-JavaScript权威指南-第三章类型、值和变量(2)
- JavaScript基础学习之-JavaScript权威指南-第三章类型、值和变量
- BZOJ 题目1016: [JSOI2008]最小生成树计数(Kruskal+Matrix_Tree)
- 如何按照顺序执行异步ajax的回调函数
- JavaScript基础学习之-JavaScript权威指南-第二章词法结构
- JavaScript基础学习之-JavaScript权威指南-第二章词法结构
- JavaScript 闭包究竟是什么
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
- JS中如何实现每点击一次按钮,显示一条信息
- JavaScript基础学习之-JavaScript权威指南-第三章类型、值和变量
- JavaScript基础学习之-JavaScript权威指南-3.10变量作用域
- Json.Net学习.集合序列化.
- Json.Net学习(1) 实现简单的序列化和反序列化
- 【 D3.js 入门系列 --- 9.6 】 生产的包图