关于Android开发完全讲义将网络图像装载到ListView控件的修改

今天看9.1节的可装载网络数据的控件这一节的内容,发现随着Android版本的更新,这部分的代码由于Android已经不允许在主程序中添加任何关于网络请求的代码而失效了(弹出android.os.NetworkOnMainThreadException异常),因此,我将代码修改成了以下:

注意:本文中程序因为要连接网络,所以一定要在AndroidManifest.xml中加入Internet权限:

主程序中的变量:

private ApkListAdapter apkListAdapter;
	public static Handler mHandler;
	private final int APK_LIST_FINISHED = 1;
	private ListView listView;
	private String rootUrl = "http://10.108.77.85:8080/myhttp/";
	private Context context;
	private String listUrl = rootUrl + "list.txt";

主函数的onCreate()方法:

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		listView = (ListView) findViewById(R.id.activity_main_listView);
		mHandler = new Handler() {//使用Handle对加载完成的数据进行UI的更新
			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				if (msg.what == APK_LIST_FINISHED) {
					Log.i("Connection", "handleMessage");
					listView.setAdapter(apkListAdapter);
				}
			}
		};
		Thread thread = new Thread(new Runnable() {//新建一个线程,将网上的数据下载下来,并且通过handle的sendMessage()方法发送到mHandle中

			@Override
			public void run() {
				// TODO Auto-generated method stub
				List list = getImageData(listUrl);
				Iterator iterator = list.iterator();
				while (iterator.hasNext()) {
					ImageData tempImageData;
					tempImageData = iterator.next();
					InputStream is = getNetInputStream(rootUrl
							+ tempImageData.url);
					tempImageData.bitmap = BitmapFactory.decodeStream(is);
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					Log.i("Connection", tempImageData.toString());

				}
				apkListAdapter = new ApkListAdapter(list, MainActivity.this);
				Message msg = new Message();
				msg.what = APK_LIST_FINISHED;
				msg.obj = apkListAdapter;
				mHandler.sendMessage(msg);
			}
		});
		thread.start();//开启下载线程
	}
ImageData类:
class ImageData {//跟书上内容对比,我加入了Bitmap,这样可以直接将Bitmap封装进去
		public String url;
		public String applicationName;
		public float rating;
		public Bitmap bitmap;

		@Override
		public String toString() {
			return "ImageData [url=" + url + ", applicationName="
					+ applicationName + ", rating=" + rating + "]";
		}

	}

跟书上基本没有变化的类和方法:

getImageData方法

public List getImageData(String urlStr) {
		List imageDataList = new ArrayList<>();
		ImageData imageData;
		InputStream is = getNetInputStream(urlStr);
		InputStreamReader isr;
		try {
			isr = new InputStreamReader(is, "GBK");
			BufferedReader br = new BufferedReader(isr);
			String s = null;
			while ((s = br.readLine()) != null) {
				String[] data = s.split(",");
				if (data.length > 2) {
					imageData = new ImageData();
					imageData.url = data[0];
					imageData.applicationName = data[1];
					imageData.rating = Float.parseFloat(data[2]);
					imageData.toString();
					imageDataList.add(imageData);
				}
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			is.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return imageDataList;
	}
getNetInputStream方法:
private InputStream getNetInputStream(String urlStr) {
		InputStream is = null;
		try {
			URL url = new URL(urlStr);
			URLConnection conn = url.openConnection();
			Log.i("Connection", conn.toString());
			conn.connect();
			is = conn.getInputStream();
			return is;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return is;
	}

继承BaseAdapter的ApkListAdapter类(稍微有点修改,已用红色标注):

class ApkListAdapter extends BaseAdapter {
		private List imageDataList;
		private LayoutInflater mInflater;

		Context context;

		public ApkListAdapter(List list, Context context) {
			// TODO Auto-generated constructor stub
			this.imageDataList = list;
			this.mInflater = LayoutInflater.from(context);
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return imageDataList.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View view = mInflater.inflate(R.layout.apklistadapter, null);
			ImageView imageView = (ImageView) view
					.findViewById(R.id.listadapter_imageView);
			TextView textViewApplicationName = (TextView) view
					.findViewById(R.id.listadapter_textView);
			TextView textViewRatingBar = (TextView) view
					.findViewById(R.id.listadapter_ratingTextView);
			RatingBar ratingBar = (RatingBar) view
					.findViewById(R.id.listadapter_ratingBar);
			textViewApplicationName
					.setText(imageDataList.get(position).applicationName);
			textViewRatingBar.setText(String.valueOf(imageDataList
					.get(position).rating));
			ratingBar.setRating(imageDataList.get(position).rating);
			imageView.setImageBitmap(imageDataList.get(position).bitmap);
			return view;
		}

	}
最后是实现的效果图(偷懒没有修改RatingBar的大小,不过默认样式的RatingBar真的是太反人类了。。。):

关于Android开发完全讲义将网络图像装载到ListView控件的修改_第1张图片

转载请注明来源:http://blog.csdn.net/simpsonst

你可能感兴趣的:(Android,listview,Android开发完全讲义,android,网络传输)