解析JSON数据,并从其中的图片地址取图片

首先,要解决的是取JSON对象,JSON对象里面还嵌套了3个JSON对象,然后其中一个JSON对象又嵌套了一个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;

		private 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");
					// 这儿就可以用我们的循环遍历方法去操作我们的数组了


 

 

 

 

  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值