通过inputStream读取网页信息。 我们定义一个方法用于读取输入流: public String readStream(InputStream is){ InputStreamReader isr; String result=""; try { String line=""; isr = new InputStreamReader(is,"utf-8"); BufferedReader br = new BufferedReader(isr); while((line = br.readLine())!=null){ result += line; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } 其中,传进参数InputStream is 是字节流,InputStreamReader(is,"utf-8")将字节流转化为字符流,再通过BufferedReader封装,以BufferedReader形式读取出来,最终拼接到字符串result里面。这样就完成了整个数据的读取。 既然读取了JSON字符串,接下来把它转换为我们想要的数据。
格式转换:将 JSON 字符串转换为我们想要的数据。这里仅仅先实现字符串的获取。其中 Log.d("xys",jsonString)是把json字符串以日志的形式打印出来。 InputStream is由 new URL(url).openStream()获得。此句功能与url.openConnection.getInputStream()相同,可根据URL直接联网获取网络数据,简单粗暴!返回值类型为InputStream。 另外,不要忘记在配置文件中添加网络权限:<uses-permission android:name="android.permission.INTERNET"></uses>
1 public class MainActivity extends ActionBarActivity { 2 private ListView listView; 3 private static String URL = "http://www.imooc.com/api/teacher?type=4&num=30"; 4 NewAsyncTask task; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.main); 10 listView = (ListView) findViewById(R.id.listtView1); 11 task = new NewAsyncTask(); 12 task.execute(URL); 13 } 14 15 // 实现网络异步访问 16 class NewAsyncTask extends AsyncTask<String, Void, List<NewsBean>> { 17 @Override 18 protected void onPostExecute(List<NewsBean> result) { 19 // TODO Auto-generated method stub 20 super.onPostExecute(result); 21 NewAdapter adapter = new NewAdapter(MainActivity.this, result); 22 listView.setAdapter(adapter); 23 24 } 25 26 @Override 27 protected List<NewsBean> doInBackground(String... params) { 28 // TODO Auto-generated method stub 29 30 return getJsonData(params[0]); 31 } 32 33 // 将URL对应的Jeson格式数据转化为我们所封装的NewsBean对象 34 private List<NewsBean> getJsonData(String URL) { 35 // TODO Auto-generated method stub 36 List<NewsBean> newsBeanlist = new ArrayList<NewsBean>(); 37 try { 38 String jString = readstream(new java.net.URL(URL).openStream()); 39 // Log.i("--->>", jString); 40 JSONObject jsonObject; 41 NewsBean newsBean; 42 try { 43 jsonObject = new JSONObject(jString); 44 JSONArray jsonArray = jsonObject.getJSONArray("data"); 45 for (int i = 0; i < jsonArray.length(); i++) { 46 jsonObject = jsonArray.getJSONObject(i); 47 newsBean = new NewsBean(); 48 newsBean.newsiconUrl = jsonObject.getString("picSmall"); 49 newsBean.newsTitle = jsonObject.getString("name"); 50 newsBean.newsContent = jsonObject 51 .getString("description"); 52 newsBeanlist.add(newsBean); 53 } 54 55 } catch (JSONException e) { 56 // TODO Auto-generated catch block 57 e.printStackTrace(); 58 } 59 60 } catch (MalformedURLException e) { 61 // TODO Auto-generated catch block 62 e.printStackTrace(); 63 } catch (IOException e) { 64 // TODO Auto-generated catch block 65 e.printStackTrace(); 66 } 67 return newsBeanlist; 68 } 69 70 // 通过InputStream解析返回数据 71 private String readstream(InputStream iStream) { 72 InputStreamReader isr; 73 String result = ""; 74 try { 75 String line = ""; 76 isr = new InputStreamReader(iStream, "utf-8"); 77 BufferedReader br = new BufferedReader(isr); 78 try { 79 while ((line = br.readLine()) != null) { 80 result += line; 81 82 } 83 } catch (IOException e) { 84 // TODO Auto-generated catch block 85 e.printStackTrace(); 86 } 87 } catch (UnsupportedEncodingException e) { 88 // TODO Auto-generated catch block 89 e.printStackTrace(); 90 } 91 return result; 92 93 } 94 95 } 96 }
------------------------------------------------------------
1 public class NewAdapter extends BaseAdapter { 2 private List<NewsBean> mList; 3 private LayoutInflater mInflater; 4 private ImageLoader mImageLoader; 5 6 public NewAdapter(Context context, List<NewsBean> data) { 7 // TODO Auto-generated constructor stub 8 mList = data; 9 mInflater = LayoutInflater.from(context); 10 mImageLoader = new ImageLoader(); 11 } 12 13 @Override 14 public int getCount() { 15 // TODO Auto-generated method stub 16 return mList.size(); 17 } 18 19 @Override 20 public Object getItem(int position) { 21 // TODO Auto-generated method stub 22 return mList.get(position); 23 } 24 25 @Override 26 public long getItemId(int position) { 27 // TODO Auto-generated method stub 28 return position; 29 } 30 31 @Override 32 public View getView(int position, View convertView, ViewGroup parent) { 33 // TODO Auto-generated method stub 34 viewHolder vHolder = null; 35 if (convertView == null) { 36 vHolder = new viewHolder(); 37 convertView = mInflater.inflate(R.layout.item_layout, null); 38 vHolder.tvicon = (ImageView) convertView 39 .findViewById(R.id.imageview); 40 vHolder.tvconten = (TextView) convertView 41 .findViewById(R.id.content); 42 vHolder.tvtitle = (TextView) convertView.findViewById(R.id.title); 43 44 convertView.setTag(vHolder); 45 46 } else { 47 vHolder = (viewHolder) convertView.getTag(); 48 } 49 vHolder.tvicon.setImageResource(R.drawable.ic_launcher); 50 51 String url = mList.get(position).newsiconUrl; 52 vHolder.tvicon.setTag(url); 53 // 多线程加载 54 // new 55 // ImageLoader().showImageByThread(vHolder.tvicon,mList.get(position).newsiconUrl); 56 // 异步加载图片 57 mImageLoader.ShowImageByAsycnTask(vHolder.tvicon, url); 58 59 vHolder.tvtitle.setText(mList.get(position).newsTitle); 60 vHolder.tvconten.setText(mList.get(position).newsContent); 61 return convertView; 62 } 63 64 class viewHolder { 65 public TextView tvtitle, tvconten; 66 public ImageView tvicon; 67 68 } 69 70 }
package com.example.zy_item; public class NewsBean { public String newsiconUrl; public String newsTitle; public String newsContent; }
1 public class ImageLoader { 2 private String murl; 3 private ImageView mimageView; 4 // 创建Cache 5 private LruCache<String, Bitmap> mCache; 6 7 public ImageLoader() { 8 // TODO Auto-generated constructor stub 9 // 获取最大可用内存 10 int maxMemory = (int) Runtime.getRuntime().maxMemory(); 11 int CacheSize = maxMemory / 4; 12 mCache=new LruCache<String, Bitmap>(CacheSize){ 13 14 @Override 15 protected int sizeOf(String key, Bitmap value) { 16 // TODO Auto-generated method stub 17 return value.getByteCount(); 18 } 19 }; 20 21 22 } 23 24 // 增加到缓存 25 public void addBitmapToCache(String url, Bitmap bitmap) { 26 if (getBitmapFromCache(url) == null) { 27 mCache.put(url, bitmap); 28 } 29 } 30 31 // 从缓存中获取数据 32 public Bitmap getBitmapFromCache(String url) { 33 return mCache.get(url); 34 } 35 36 private Handler mhandler = new Handler() { 37 @Override 38 public void handleMessage(Message msg) { 39 // TODO Auto-generated method stub 40 super.handleMessage(msg); 41 if (mimageView.getTag().equals(murl)) 42 43 mimageView.setImageBitmap((Bitmap) msg.obj); 44 } 45 46 }; 47 48 // 多线程加载 49 public void showImageByThread(ImageView imageView, final String url) { 50 51 mimageView = imageView; 52 murl = url; 53 new Thread() { 54 55 @Override 56 public void run() { 57 // TODO Auto-generated method stub 58 super.run(); 59 Bitmap bitmap = getBitmapFromURL(url); 60 Message message = Message.obtain(); 61 message.obj = bitmap; 62 mhandler.sendMessage(message); 63 } 64 65 }.start(); 66 67 } 68 69 public Bitmap getBitmapFromURL(String urlString) { 70 Bitmap bitmap; 71 InputStream iStream = null; 72 73 try { 74 URL url = new URL(urlString); 75 HttpURLConnection connection = (HttpURLConnection) url 76 .openConnection(); 77 78 iStream = new BufferedInputStream(connection.getInputStream()); 79 bitmap = BitmapFactory.decodeStream(iStream); 80 connection.disconnect(); 81 return bitmap; 82 } catch (IOException e) { 83 // TODO Auto-generated catch block 84 e.printStackTrace(); 85 } finally { 86 87 try { 88 iStream.close(); 89 } catch (IOException e) { 90 // TODO Auto-generated catch block 91 e.printStackTrace(); 92 } 93 94 } 95 96 return null; 97 98 } 99 100 // 基于AsycnTask加载: 101 public void ShowImageByAsycnTask(ImageView imageView, String url) { 102 // 从缓存中取出对应图片 103 Bitmap bitmap = getBitmapFromCache(url); 104 // 如果缓存中没有,那么必须去下载 105 if (bitmap == null) { 106 new NewAsyncTask(imageView, url).execute(url); 107 } 108 109 else { 110 imageView.setImageBitmap(bitmap); 111 } 112 } 113 114 private class NewAsyncTask extends AsyncTask<String, Void, Bitmap> { 115 private ImageView mImageView; 116 private String murl; 117 118 public NewAsyncTask(ImageView imageView, String url) { 119 // TODO Auto-generated constructor stub 120 mImageView = imageView; 121 murl = url; 122 } 123 124 @Override 125 protected Bitmap doInBackground(String... params) { 126 // TODO Auto-generated method stub 127 // 从网络获取图片 128 String ur =params[0]; 129 Bitmap bitmap = getBitmapFromURL(ur); 130 if (bitmap != null) { 131 // 将不在缓存的图片加入缓存 132 addBitmapToCache(ur, bitmap); 133 } 134 return bitmap; 135 } 136 137 @Override 138 protected void onPostExecute(Bitmap result) { 139 // TODO Auto-generated method stub 140 super.onPostExecute(result); 141 if (mImageView.getTag().equals(murl)) 142 143 mImageView.setImageBitmap(result); 144 } 145 146 } 147 148 }
Android 异步加载的总结 1. 通过异步加载,避免阻塞UI线程,从而实现了网络的异步访问。这是基础,也是 Android 要求我们这么做的。 2. 通过 LruCache,将已经下载的图片放到内存中,以一个缓存避免多次重复的下载,提高用户的体验。当然,这里只介绍了内存缓存,我们还可以使用 DiskLruCache ,将内存中的图片保存到硬盘中,保存到存储器中,做为一个持久化的缓存,这也称作“二级缓存”。而内存缓存便叫做“一级缓存”。 3. 通过判断 ListView 的滑动状态,决定什么时候该加载图片,什么时候不该加载图片,而让ListView平滑地去滚动。在这一点上我们是通过对 ListView 的滑动状态的监听,去实现这样的操作,将加载图片的控制权由 getView() 转移到我们的滑动事件,从而让复杂的 ListView 也能实现流畅的异步加载。 4. 不仅仅是 ListView ,任何控件都可以使用异步加载,这里以 ListView 作为例子的原因是因为它比较常用。异步加载不仅仅用于获取网络图片,所有的耗时操作我们都可以认为是异步加载,通过异步的方式,去将这些耗时操作与主线程分开,从而提升用户体验,这也是异步加载的核心所在。