您的位置:首页 > Web前端 > JavaScript

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

2015-08-12 21:22 1326 查看
首先,要解决的是取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;

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


 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: