1. 创建方法, 网络地址的获取开发步骤:
3. 访问网络是一个敏感的操作 需要网络使用的权限
java.net.SocketException:socket failed: EACCES (Permission denied)
在AndroidManifest.xml文件中,配置使用权限
1. 错误的线程被调用的异常:只有主线程才能创建 修改View。
2. 使用runOnUIThread(Runnable) 该方法内运行的代码为主线程代码
在该项目中 我们反复点击上一张图片或者下一张图片 则发现循环请求网络图片 这个时候需要将网络的图片进行一个缓存。
如果图片文件在本地存在,则直接从文件里取出来显示到图片控件上。如果不存在,则从网络中获取。
1. 将Bitmap保存到本地
//1. 保存的图片格式 由CompressFormat枚举定义
//2. 保存的质量
//3. 将文件保存到哪个地方
bitmap.compress(CompressFormat.PNG, 100, fos);
2. 将文件转化成Bitmap
File file=newFile(getFilesDir(),getSavedImagePath(urlPath));
Bitmap bitmap =BitmapFactory.decodeStream(new FileInputStream(file));
开发步骤:
1. 创建URL对象
URL url=new URL(urlPath);
2. 打开一个Http链接
HttpUrlConnectionconn=(HttpUrlConnection)url.openConnection();
3. 获取服务器的返回码
intcode=conn.getResponseCode;
4. 如果返回码为200,就去获取数据(数据流返回)
intis=conn.getInputStream();
注意点:
1. 创建一个多线程做网络请求。
2. 添加网络权限
3. 返回主线程 修改、更新UI控件开发步骤:
1. 创建Handler对象
2.在另一条线程里面通过Handler向主线程发送消息
3.handleMessage()处理其他线程发送过来的消息
注意点:
* 当多条线程向主线程发送消息的时候 msg.what;
* 当另外一条线程向主线程 想携带信息给主线程 msg.obj;轻量级的msg.arg1 msg.arg2
源码的实现分析:
Handler: 发送消息 处理消息
Message:判断消息类型 携带数据
MessageQueue: 存储一个消息队列
Looper:
sendMessage(Messagemsg):进入到MessageQueue(死循环 将消息放到消息队列里面)
sendMessageDelayed(Messagemsg, long delayMillis)
sendMessageAtTime(Messagemsg, long uptimeMillis)
enqueueMessage(MessageQueuequeue, Message msg, long uptimeMillis)
queue.enqueueMessage(msg,uptimeMillis);
handleMessage(msg);
dispatchMessage(Messagemsg)
系统默认会调用Looper:
prepareMainLooper()初始化Looper对象
prepare(booleanquitAllowed)
loop() 做一个死循环 只有消息队列里有消息 就调用Handler去处理
结论:
1. 当系统启动的时候 会在application里面调用prepareMainLooper()-->prepare(booleanquitAllowed) 初始化Looper对象
2. 调用Looper对象的 loop() 做一个死循环
3. 当mHandler.sendMessage(message); --> 将 Message添加到MessageQueue里面去
4. loop()方法取出MessageQueue ,通过MessageQueue 找到Message. 调通msg.target 去分发消息dispatchMessage(msg)
5. msg.target ==Handler :dispatchMessage()调用handleMessage(Message msg);
需求: 读取后台提供的news.xml文件 将其转换成为列表控件
技术分析: 网络数据的获取 xml文件解析 列表的展示 控件的重写
开发步骤:
1. 网络的获取:
* 在AndroidMenifest.xml中配置使用的网络权限。
* 创建一条线程进行网络请求(网络请求步骤见上)
2. xml文件解析:
* 创建pull解析器
* 读取输入流
* 开始解析文档 (注意不要死循环)
3. 列表展示
* 获取列表控件 绑定适配器
* 当数据获取成功后 通过Handler对象通知主线程修改列表
* 主线程调用适配器重刷界面
4. 控件重写 (因为图片控件默认没有提供直接设置网络地址的方法不满足需求)
* 创建一个类继承ImageView
* 在布局中使用该控件
* 代码中获取控件 并调用自定义的方法
第三方包:android-smart-image-view-master
图片控件加载原理:
1. 先去缓存里面看下有没有 如果有 直接去缓存里面取
2. 如果缓存里面没有 去本地找 如果找到了 先将本地加载到缓存里去 再从缓存中取
3. 如果本地没有 就去网络里面找 1.下载到本地 2.加载到缓存 3.显示图片
4. 如果全部都找不到 需要默认给个图片
开发步骤:
1. 将src下的代码复制到项目中
2. 设置网络的使用权限
3. 在布局中创建控件标签
4. 在代码中获取控件并引用