1. 网络连接基本

 //通过指定URL获取原始数据,并返回一个字节流数组。
public byte[] getUrlBytes(String urlSpec)throws IOException{ //根据传入的字符串参数,创建一个URL对象
URL url = new URL(urlSpec);
//通过url.openConnection()方法得到HttpUrlConnection对象。
HttpURLConnection connection = (HttpURLConnection)url.openConnection(); try{
ByteArrayOutputStream out = new ByteArrayOutputStream();
/*
* 虽然 HttpURLConnection 对象提供了一个连接,但只有在调用 getInputStream() 方法时
* (如果是POST请求,则调用 getOutputStream() 方法),它才会真正连接到指定的URL地址。
*/
InputStream in = connection.getInputStream(); //如果连接失败就抛出错误
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
throw new IOException(connection.getResponseMessage() + ": with" + urlSpec);
} //写入
int bytesRead = 0;
byte[] buffer = new byte[1024];
while((bytesRead = in.read(buffer)) > 0){
out.write(buffer,0,bytesRead);
}
out.close();
return out.toByteArray();
}finally {
connection.disconnect();
}
} //将getUrlBytes(String)方法返回的结果转换成String
public String getUrlString(String urlSpec)throws IOException{
return new String(getUrlBytes(urlSpec));
}

最后记得在AndroidManifest.xml文件中添加联网权限。

2. 线程与主线程

线程是个单一执行序列。单个线程中的代码会逐步执行。所有Android应用的运行都是从主线程开始的。然而,主线程不是线程那样的预定执行序列。相反,它处于一个无限循环的运行状态,等待着用户或系统触发事件的发生。事件触发后,主线程便负责执行代码,以响应这些事件。

事件处理循环让UI代码得以按顺序执行。这可以保证任何事件处理都不会发生冲突,同时代码也能够快速响应执行。

网络连接需要时间,Web 服务器可能需要1~2秒的时间来响应访问请求,文件下载则耗时更久。考虑到这个因素,android 禁止任何主线程网络连接行为。即使强行在主线程中进行网络连接,Android 也会抛出 NetworkOnMainThreadException 异常。

而网络连接相比其他任务更耗时。等待响应期间,用户界面毫无反应,这可能会导致应用无响应(Application Not Responding,ANR)现象发生,也就是一个弹框,要求你关闭应用。 
怎样使用后台线程最容易呢?答案就是使用 AsyncTask 类。

3. AsyncTask

AsyncTask是一个抽象类
在继承AsyncTask类的时候指定3个泛型参数
[1] Params 在执行AsyncTask时需要传入的参数,可用于在后台任务中使用
[2] Progress 后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位
[3] Result 当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型 public class DownloadTask extends AsyncTask<Void,Integer,Boolean> { //这个方法在后台任务开始执行之前调用,用于进行一些界面上的初始化操作
@Override
protected void onPreExecute() {
progressDialog.show(); //显示进度对话框
super.onPreExecute();
} //当后台任务执行完毕并通过return语句进行返回时,这个方法很快会被调用
@Override
protected void onPostExecute(Boolean aBoolean) {
progressDialog.dismiss();//关闭进度对话框
if(result){
Toast.makeText(context,"Download successedd",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context,"Download failed",Toast.LENGTH_SHORT).show();
}
super.onPostExecute(aBoolean);
} //当在后台调用了publishProgress(progress...)方法后 此方法很快会被调用 可以对UI进行操作
@Override
protected void onProgressUpdate(Integer... values) {
//在这里更新下载进度
progressDialog.setMessage("Download"+values[0]+"%");
super.onProgressUpdate(values);
} //此方法的代码会在子线程中运行,处理耗时任务用,此方法不可以进行UI操作,但可以调用publishProgress(progress...)来完成
@Override
protected Boolean doInBackground(Void... params) {
try{
while(true){
int downloadPercent = doDownload(); //这是一个虚构的方法
publishProgress(downloadPercent);
if(downloadPercent >= 100)
break;
}
}catch (Exception e){
return false;
}
return null;
}
}

AsyncTask的取消

AsyncTask.cancel(boolean) 方法有两种工作模式:粗暴的和温和的。如果调用 cancel(false) 方法,它只是温和地设置 isCancelled() 的状态为 true 。随后, AsyncTask 会检查doInBackground(...) 方法中的 isCancelled() 状态,然后选择提前结束运行。

如果调用 cancel(true) 方法,它会粗暴地终止 doInBackground(...) 方法当前所在的线程。

应该在什么时候、什么地方撤销 AsyncTask 呢?

要看情况了。先问问自己,如果fragment或activity已销毁了或是看不到了, AsyncTask 当前的工作可以停止吗?如果可以,就在onStop(...) 方法里(看不到视图),或者在 onDestroy(...) 方法里(fragment/activity实例已销毁)撤销 AsyncTask 实例。

即使fragment/activity已销毁了(或者视图已看不到了),也可以不撤销 AsyncTask ,让它运
行至结束。不过,这可能会引发潜在的内存泄漏,也可能会出现UI更新问题(因为UI已失效)。如果不管用户怎么操作,一定要保证重要工作的完成,可以考虑其他解决方案,比如使用 Service。

AsyncTask 的替代方案

AsyncTaskLoader:是个抽象Loader,可以使用 AsyncTask 把数据加载工作转移到其他线程上。我们创建的loader类几乎都是 AsyncTaskLoader 的子类。 AsyncTaskLoader 能在不阻塞主线程的前提下获取到数据,并把结果发送给目标对象。

LoaderManager 会帮我们妥善管理loader及其加载的数据。而且, LoaderManager 还负责启动和停止loader,以及管理loader的生命周期。

4. JSON解析

JSON对象是一系列包含在 { } 中的名值对。JSON数组是包含在 [ ] 中用逗号隔开的JSON对象列表。对象彼此嵌套形成层级关系。

son.org API提供有对应JSON数据的Java对象,如 JSONObject 和 JSONArray 。使用JSONObject(String) 构造函数,可以很方便地把JSON数据解析进相应的Java对象。更新fetchItems() 方法执行解析任务

                      左边为要解析的JSON数据。

JSONObejct解析代码如下:

private void parseItems(List<GalleryItem> items, JSONObject jsonBody)throws IOException,JSONException{

        //得到叫做photos的嵌套JSONObject
JSONObject photosJsonObject = jsonBody.getJSONObject("photos");
//得到photos里面的叫photo的JSONArray
JSONArray photoJsonArray = photosJsonObject.getJSONArray("photo"); //JsonArray中包含若干个JSONObject, 将这些数据一一取出。
for(int i=0; i<photoJsonArray.length(); i++){
JSONObject photoJsonObject = photoJsonArray.getJSONObject(i); GalleryItem item = new GalleryItem(); item.setId(photoJsonObject.getString("id"));
item.setCaption(photoJsonObject.getString("title")); //并不是每个图片都有对应的url_s连接,所以需要添加一个检查。
if(!photoJsonObject.has("url_s")){
continue;
} item.setUrl(photoJsonObject.getString("url_s"));
items.add(item);
}

Gson解析方式在23章的挑战练习中。

安卓权威编程指南-笔记(第23章 HTTP与后台任务)的更多相关文章

  1. 安卓权威编程指南 -笔记(19章 使用SoundPool播放音频)

    针对BeatBox应用,可以使用SoundPool这个特别定制的实用工具. SoundPool能加载一批声音资源到内存中,并支持同时播放多个音频文件.因此所以,就算用户兴奋起来,狂按按钮播放全部音频, ...

  2. 安卓权威编程指南 -笔记(18章 处理assets)

    resources资源可以存储声音文件,但当处理多个音乐文件时,效率会很低. assets可以被看作随应用打包的微型文件系统,支持任意层次的文件目录结构.类似游戏这样需要加载大量图片和声音资源的应用通 ...

  3. 安卓权威编程指南-笔记(第21章 XML drawable)

    在Andorid的世界里,凡事要在屏幕上绘制的东西都可以叫drawable,比如抽象图形,Drawable的子类,位图图形等,我们之前用来封装图片的BitmapDrawable就是一种drawable ...

  4. 安卓权威编程指南-笔记(第27章 broadcast intent)

    本章需求:首先,让应用轮询新结果并在有所发现时及时通知用户,即使用户重启设备后还没有打开过应用.其次,保证用户在使用应用时不出现新结果通知. 1. 一般intent和broadcast intent ...

  5. 安卓权威编程指南-笔记(第22章 深入学习intent和任务)

    本章,我们会使用隐式intent创建一个替换android默认启动器的应用.名为NerdLauncher. NerdLauncher应用能列出设备上的其他应用,点选任意列表项会启动相应应用. 1. 解 ...

  6. 安卓权威编程指南-笔记(第24章 Looper Handler 和 HandlerThread)

    AsyncTask是执行后台线程的最简单方式,但它不适用于那些重复且长时间运行的任务. 1. Looper Android中,线程拥有一个消息队列(message queue),使用消息队列的线程叫做 ...

  7. 安卓权威编程指南 挑战练习 25章 深度优化 PhotoGallery 应用

    你可能已经注意到了,提交搜索时, RecyclerView 要等好一会才能刷新显示搜索结果.请接受挑战,让搜索过程更流畅一些.用户一提交搜索,就隐藏软键盘,收起 SearchView 视图(回到只显示 ...

  8. 安卓权威编程指南 - 第五章学习笔记(两个Activity)

    学习安卓编程权威指南第五章的时候自己写了个简单的Demo来加深理解两个Activity互相传递数据的问题,然后将自己的学习笔记贴上来,如有错误还请指正. IntentActivityDemo学习笔记 ...

  9. 安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)

    26.11 挑战练习:在 Lollipop 设备上使用 JobService 请创建另一个 PollService 实现版本.新的 PollService 应该继承 JobService 并使用 Jo ...

随机推荐

  1. android新闻项目、饮食助手、下拉刷新、自定义View进度条、ReactNative阅读器等源码

    Android精选源码 Android仿照36Kr官方新闻项目课程源码 一个优雅美观的下拉刷新布局,众多样式可选 安卓版本的VegaScroll滚动布局 android物流详情的弹框 健身饮食记录助手 ...

  2. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:读取MNIST手写图片数据写入的TFRecord文件

    import numpy as np import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_dat ...

  3. Opencv笔记(十八)——轮廓的更多函数及其层次结构

    凸缺陷 前面我们已经学习了轮廓的凸包,对象上的任何凹陷都被成为凸缺陷.OpenCV 中有一个函数 cv.convexityDefect() 可以帮助我们找到凸缺陷.函数调用如下: hull = cv2 ...

  4. Opencv笔记(九)——图像阈值

    学习目标: 学习简单阈值,自适应阈值,Otsu's 二值化等 学习函数cv2.threshold,cv2.adaptiveThreshold 等. 一.简单阈值 与名字一样,这种方法非常简单.但像素值 ...

  5. Office、VBA开发方案选择指南

    最近很多朋友向我提出Office的开发方式方面的疑惑,主要是针对特定的系统和Office版本不知道选择哪一种编程语言.创建哪一种类型的项目. 事实确实如此,如果搞不清楚语言的特性和项目类型的特点,很可 ...

  6. VUEJS文件扩展名esm.js和common.js是什么意思

    vue.js : vue.js则是直接用在<script>标签中的,完整版本,直接就可以通过script引用. vue.common.js :预编译调试时,CommonJS规范的格式,可以 ...

  7. redis簡單命令

  8. 感叹号在Linux bash中使用技巧

    1. 重复执行上一条指令  !! [root@iZ23t6nzr7dZ python]# ls /usr/local/ aegis bin etc games include lib lib64 li ...

  9. 主效应|处理误差 |组间误差|处理效应|随机误差|组内误差|误差|效应分析|方差齐性检验|SSE|SSA|SST|MSE|MSA|F检验|关系系数|完全随机化设计|区组设计|析因分析

    8 什么是只考虑主效应的方差分析? 就是不考虑交互效应的方差分析,即认为因素之间是不相互影响的,就是无重复的方差分析.   什么是处理误差 (treatment error).组间误差(between ...

  10. HTML5 Fundamental Syntax

    HTML5 Fundamental Syntax */--> HTML5 Fundamental Syntax 1 Adding Document Structure with HTML5's ...