高仿糗事百科学习(三)NET
2016-04-19 19:13
197 查看
高仿糗事百科,是一个典型的cs模式,所以我们获取数据就要通过net,今天我就开始书写关于网络连接方面的书写。
在安卓中,我们将联网请求往往是放在次线程中,如果放在主线程中,将会导致主线程要处理事件太多导致崩溃,而放在次线程中,那么将出现管理线程的问题,于是我们就可以使用一个线程池辅助类ThreadPoolUtils
有了ThreadPoolUtils我们就可以管理线程
下面开始书写第一个关于网络get请求的请求线程:
在这个线程中我们主要做了两件事:
一个是通过String result = myGet.doGet(url);这段代码在NET工具类中通过url获取所需要的数据
第二件事是通过handler的message将下载进程与主ui进程进行交互用来更新ui中的数据.
下面就进入myGet工具类:
通过调用MyGet工具类获取服务器中的信息,其中谷歌公司对HttpGet进行了屏蔽,我们需要去apache官网去下载httpcilent和httpcore两个jar包进行方法的导入
有了以上的下载线程已经get获取工具,我们还需要在Fragment中进行进程的启动,在HotFragment中我们是在createListModel()方法中进行数据的加载,根据干货、嫩草、文字我们进行url的切换从而访问不同的数据,最后 ThreadPoolUtils.execute(new HttpGetThread(hand, url));通过进程管理工具进行网络进程的使用,其中的hand正是主ui线程的handler.
在handler中我们通过对msg传输的值进行判断是否传输成功,并且通过json解析器进行解析,将消息存进AshamedInfo list中最后通过Adapter的notifychanged通知listView进行数据的更新
上面我们将数据传输写完了,下面我们做图片加载的书写:
从内存和本地加载都十分的容易理解,但是在下载中却出现了一个回调我们可以着重观察下
首先定义的handler,通过这个handler我们可以与下载图片线程进行交互从而获取图片,然后通过回调接口,将图片传入到listViewadapter中进行图片的加载。在下载线程中我们通过DownBitmap获取了图片的输入流再通过图片工厂进行图片的绘制。
下面将DownBitmap进行书写:
因为获取图片的数据流只需要这一个类,因此我们可以通过单例模式只存在一个DownBitmap 类通过传入不同的url就可以获取不同的图片资源。
在安卓中,我们将联网请求往往是放在次线程中,如果放在主线程中,将会导致主线程要处理事件太多导致崩溃,而放在次线程中,那么将出现管理线程的问题,于是我们就可以使用一个线程池辅助类ThreadPoolUtils
/** * 线程池辅助类,整个应用程序就只有一个线程池去管理线程。 * 可以设置核心线程数、最大线程数、额外线程空状态生存时间,阻塞队列长度来优化线程池 */ public class ThreadPoolUtils { private ThreadPoolUtils() { } // 定义核心线程数,并行线程数 private static int CORE_POOL_SIZE = 3; // 线程池最大线程数:除了正在运行的线程额外保存多少个线程 private static int MAX_POOL_SIZE = 200; // 额外线程空闲状态生存时间 private static int KEEP_ALIVE_TIME = 5000; // 阻塞队列。当核心线程队列满了放入的 // 初始化一个大小为10的泛型为Runnable的队列 private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(10); // 线程工厂,把传递进来的runnable对象生成一个Thread private static ThreadFactory threadFactory = new ThreadFactory() { // 原子型的integer变量生成的integer值不会重复 private final AtomicInteger ineger = new AtomicInteger(); @Override public Thread newThread(Runnable arg0) { return new Thread(arg0, "MyThreadPool thread:" + ineger.getAndIncrement()); } }; // 当线程池发生异常的时候回调进入 private static RejectedExecutionHandler handler = new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 进行重启操作 } }; // 线程池ThreadPoolExecutor java自带的线程池 private static ThreadPoolExecutor threadpool; // 静态代码块,在类被加载的时候进入 static { threadpool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue, threadFactory, handler); } public static void execute(Runnable runnable) { threadpool.execute(runnable); } }
有了ThreadPoolUtils我们就可以管理线程
下面开始书写第一个关于网络get请求的请求线程:
public class HttpGetThread implements Runnable { private Handler hand; private String url; private MyGet myGet=new MyGet(); public HttpGetThread(Handler hand, String endParamerse) { this.hand = hand; // 拼接访问服务器完整的地址 url = Model.HTTPURL + endParamerse; } @Override public void run() { // 获取我们回调主ui的message Message msg = hand.obtainMessage(); msg = hand.obtainMessage(); Log.e("liuxiaowei", url); try { String result = myGet.doGet(url); msg.what = 200; msg.obj = result; } catch (ClientProtocolException e) { msg.what = 404; } catch (IOException e) { msg.what = 100; } hand.sendMessage(msg); } }
在这个线程中我们主要做了两件事:
一个是通过String result = myGet.doGet(url);这段代码在NET工具类中通过url获取所需要的数据
第二件事是通过handler的message将下载进程与主ui进程进行交互用来更新ui中的数据.
下面就进入myGet工具类:
public String doGet(String url) throws ClientProtocolException, IOException { String result = null;// 我们的网络交互返回值 HttpGet myGet = new HttpGet(url);//網絡請求url HttpClient httpClient = new DefaultHttpClient(); httpClient.getParams().setIntParameter( //设置连接超时 HttpConnectionParams.CONNECTION_TIMEOUT, 5 * 1000); //设置socket连接超时 httpClient.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, 30 * 1000); HttpResponse httpResponse = httpClient.execute(myGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { result = EntityUtils.toString(httpResponse.getEntity(), "utf-8"); } return result; }
通过调用MyGet工具类获取服务器中的信息,其中谷歌公司对HttpGet进行了屏蔽,我们需要去apache官网去下载httpcilent和httpcore两个jar包进行方法的导入
有了以上的下载线程已经get获取工具,我们还需要在Fragment中进行进程的启动,在HotFragment中我们是在createListModel()方法中进行数据的加载,根据干货、嫩草、文字我们进行url的切换从而访问不同的数据,最后 ThreadPoolUtils.execute(new HttpGetThread(hand, url));通过进程管理工具进行网络进程的使用,其中的hand正是主ui线程的handler.
在handler中我们通过对msg传输的值进行判断是否传输成功,并且通过json解析器进行解析,将消息存进AshamedInfo list中最后通过Adapter的notifychanged通知listView进行数据的更新
上面我们将数据传输写完了,下面我们做图片加载的书写:
/** * 控制图片的加载类 * 列表在滑动过程时,没有图片会进行下载,并保存到sdcard与 imageCaches 当中去,使用软引用进行封装,如果内存不够时 * 我们的imageCaches 当中的Bitmap对象会被清理掉,图片被释放掉 再次需要加载的时候,先从1级缓存当中获取,如果没有的话,去 * 本地获取,本地也获取不到的话,去网络下载。 一级缓存作用:对于listview当中刚刚滑动过的item显示的图片进行保存 * 二级缓存作用:对于listview当中很久前查看的图片或已经被释放掉图片 进行保存 */ public class LoadImage { //下载图片最大并行线程数 private static int MAX = 5; //图片的一级缓存 private Map<String, SoftReference<Bitmap>> imageCaches = null; // 查看本地缓存工具类 private FileUtiles fileUtiles; // android 提供给我们的一个线程池,使用方便 private ExecutorService threadPools = null; // 初始化上面的相关的变量 public LoadImage(Context ctx) { imageCaches = new HashMap<String, SoftReference<Bitmap>>(); fileUtiles = new FileUtiles(ctx); } // 加载图片时,入口 public Bitmap loadImage(final ImageView imageView, final String imageUrl, final ImageDownloadCallBack imageDownloadCallBack) { // imageUrl 由于其唯一型,把他作为我们map当中的key // 获取图片名称 final String filename = imageUrl.substring( imageUrl.lastIndexOf("/") + 1, imageUrl.length()); // 图片保存到本地时的地址 String filepath = fileUtiles.getAbsolutePath() + "/" + filename; // 查找一级缓存,看看是否有这张图片 // 如果map当中有这个key返回一个true if (imageCaches.containsKey(imageUrl)) { // 找到对应图片软引用的封装 SoftReference<Bitmap> soft = imageCaches.get(imageUrl); // 从软引用当中获取图片 Bitmap bit = soft.get(); if (bit != null) return bit; // 从我们的一级缓存(程序内部获取图片) } //从二级缓存中获取图片 if (fileUtiles.isBitmap(filename)) { Bitmap bit = BitmapFactory.decodeFile(filepath); // 在二级缓存读取的时候直接添加到一级缓存当中 imageCaches.put(imageUrl, new SoftReference<Bitmap>(bit)); return bit; } // 一级缓存,二级缓存都不存在,直接到网络加载 if (imageUrl != null && !imageUrl.equals("")) { if (threadPools == null) { // 实例化我们的线程池 threadPools = Executors.newFixedThreadPool(MAX); } // 下载回图片回调Handler final Handler hand = new Handler() { @Override public void handleMessage(Message msg) { // 如果图片下载成功,并且回调对象不为空时 if (msg.what == 111 && imageDownloadCallBack != null) { Bitmap bit = (Bitmap) msg.obj; // 调用回调自定义适配器的接口方法传递数据 imageDownloadCallBack.onImageDownload(imageView, bit); } super.handleMessage(msg); } }; // 下载图片线程 Thread thread = new Thread() { Bitmap bit = null; public void run() { // 网络下载时的字节流 InputStream inputStream = DownBitmap.getInstance() .getInputStream(imageUrl); //图片压缩到原来一般 BitmapFactory.Options op=new BitmapFactory.Options(); op.inSampleSize=6; if(Model.IMGFLAG) op.inSampleSize = 1; Bitmap bit = BitmapFactory.decodeStream(inputStream, null, op); if (bit != null) { // 添加到一级缓存当中 imageCaches.put(imageUrl, new SoftReference<Bitmap>(bit)); // 添加到二级缓存 fileUtiles.saveBitmap(filename, bit); // 传递给Handler Message msg = hand.obtainMessage(); msg.what = 111; msg.obj = bit; hand.sendMessage(msg); } } }; threadPools.execute(thread); } return null; } // 通过回调机制设置图片时的接口(类似于Button的Onclick) public interface ImageDownloadCallBack { // ImageView 你所想要设定的imageview Bitmap 想要设定的图片 void onImageDownload(ImageView imageView, Bitmap bitmap); }
从内存和本地加载都十分的容易理解,但是在下载中却出现了一个回调我们可以着重观察下
// 下载回图片回调Handler final Handler hand = new Handler() { @Override public void handleMessage(Message msg) { // 如果图片下载成功,并且回调对象不为空时 if (msg.what == 111 && imageDownloadCallBack != null) { Bitmap bit = (Bitmap) msg.obj; // 调用回调自定义适配器的接口方法传递数据 imageDownloadCallBack.onImageDownload(imageView, bit); } super.handleMessage(msg); } }; // 下载图片线程 Thread thread = new Thread() { Bitmap bit = null; public void run() { // 网络下载时的字节流 InputStream inputStream = DownBitmap.getInstance() .getInputStream(imageUrl); //图片压缩到原来一般 BitmapFactory.Options op=new BitmapFactory.Options(); op.inSampleSize=6; if(Model.IMGFLAG) op.inSampleSize = 1; Bitmap bit = BitmapFactory.decodeStream(inputStream, null, op); if (bit != null) { // 添加到一级缓存当中 imageCaches.put(imageUrl, new SoftReference<Bitmap>(bit)); // 添加到二级缓存 fileUtiles.saveBitmap(filename, bit); // 传递给Handler Message msg = hand.obtainMessage(); msg.what = 111; msg.obj = bit; hand.sendMessage(msg); } } }; threadPools.execute(thread); }
首先定义的handler,通过这个handler我们可以与下载图片线程进行交互从而获取图片,然后通过回调接口,将图片传入到listViewadapter中进行图片的加载。在下载线程中我们通过DownBitmap获取了图片的输入流再通过图片工厂进行图片的绘制。
下面将DownBitmap进行书写:
/** * 下载服务器网络图片 * */ public class DownBitmap { private DownBitmap() { } //单例设计模式 private static DownBitmap my=null; public static synchronized DownBitmap getInstance() { if (my == null) my = new DownBitmap(); return my; } // 获取网络图片下载时返回的流 public InputStream getInputStream(String Biturl){ //使用Get获取图片资源 HttpGet get=new HttpGet(Biturl); HttpParams httpParams = new BasicHttpParams(); //连接超时时间 HttpConnectionParams.setConnectionTimeout(httpParams, 5 * 1000); //设置socket超时时间 HttpConnectionParams.setSoTimeout(httpParams, 30 * 1000); HttpClient httpClient = new DefaultHttpClient(httpParams); try { HttpResponse hr = httpClient.execute(get); if (hr.getStatusLine().getStatusCode() == 200) { return hr.getEntity().getContent();// 得到服务器返回的输入流 } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }// 建立response连接从而方便获取状态吗 return null; } }
因为获取图片的数据流只需要这一个类,因此我们可以通过单例模式只存在一个DownBitmap 类通过传入不同的url就可以获取不同的图片资源。
相关文章推荐
- java设置代理服务器
- Xcode真机测试could not find developer disk image解决方法
- cf441ABC
- java初学者:类与对象 技术文章
- 利用 Travis CI 把 Android 项目部署到 github
- 堆排序
- arcgis_标注功能
- 程序员你为什么迷茫?
- 第二章ROS机器人操作系统的总体框架
- ZOJ - 3932 Handshakes (技巧)握手
- [C语言][LeetCode][86]Partition List
- springmvc jsp无法访问静态同目录的css js文件
- [SSM]使用MyBatis Generator自动创建代码
- 第八周实践项目2-用对象数据操作长方柱类
- 文本特征选择算法:卡方检验和信息增益
- WIN7下使用Xmanager连接rhel-server-6.2-i386配置
- node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】
- App 上线流程
- 自定义控件android
- 指向学生类的指针