新闻客户端–OKHttp查询
- #### ==新闻客户端==
- #### OKHttp
- #### ==进度条==
- #### 面试题:
- #### 问题
案例-新闻客户端
- 把资源放到服务器上
- 将json数据放到tomcat的webapps目录下,将里边图片url全部改成自己本机地址即可。
- 测试接口,使用tomcat连接浏览器,注意图片的IP地址连接成功就可以了
业务逻辑
连接服务器,开启网络请求,获取服务器数据news.josn文件
- 用HttpURLConnection获取网络请求
- 连接网络请求
==注意:添加权限==
new Thread(new Runnable() { @Override public void run() { try { //传Tomact所在电脑的IP地址 //有个特殊的IP:10.0.2.2 URL url = new URL("http://10.0.2.2:8080/news/news.json"); InputStream is = url.openConnection().getInputStream(); //转换为字符串 String json = StreamUtils.in2Str(is); List<News> newsList = parseJson(json); } catch (Exception e) { e.printStackTrace(); } } }).start();
解析服务器数据,将解析出来的数据封装到List
- 定义一个集合存放解析出来的数据
List newsList =parse(json); 定义一个获取json数据的方法,返回类型List
``` protected List<News> parseJson(String json) throws JSONException { List<News> newsList = new ArrayList<News>(); JSONArray jsonArray = new JSONArray(json); for(int i=0;i<jsonArray.length();i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); News news = new News(); news.title = jsonObject.getString("title"); news.description = jsonObject.getString("description"); news.image = jsonObject.getString("image"); news.type = jsonObject.getInt("type"); //必须先判断有没有这个字段,如果有再去获取 if (jsonObject.has("comment")) { news.comment = jsonObject.getInt("comment"); } //注意:千万别忘记 newsList.add(news); } return newsList; } ```
在子线程中得到数据并解析之后,将数据通过Handler发送给主线程,然后加载ListView
给ListView设置Adapter(修改UI操作)
- 在myAdapter设置布局时,记得要添加上下文
获取json中的image路径
- 再发一次网络请求获取网络上的图片资源
- 通过第三方框架来获取图片
- 把资源放到服务器上
OKHttp 第三方框架
OKHttp的步骤:
1、 创建一个OKHttp框架的核心对象OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient();
2、 创建一个请求对象Request
Request request = new Request() .Build() //new一个 builder对象
.url(”url”) //地址
.build();
Request使用的是**构建者设计模式**,它的构造函数被隐藏不能直接去new,需要创建出来它的Build对象,通过Build去构架一个Request对象
3、 生成一个请求任务
- 如果是get请求则直接获取请求任务
- 如果是POST请求,需要获取一下请求体
- 获取请求体
```
FormBody body = new FormBody.Builder()
.add(key,value)//添加键和值
.build();
```
- 请求任务
```
Call call = okHttpClient.newCall(request)
```
Call可以把Request构建的请求协议转换一个请求任务。
4、 执行任务
- 把call添加到任务线,一添加进去就会被立即执行
- 当服务器返回数据的时候,call对象要回调该方法
- response 就代表了服务器给我们返回的所有的数据
- 用一个字符串接收返回的数据请求体结果
- 通过Handler调用**obtainMessage(int what,new object)** 在调用
**sendToTarget()** 把object传给Handler的 **handleMessage()** 来设置UI
```
call.enqueue(new Callback() {
// 当服务器返回数据的时候,call对象要回调该方法
// response 就代表了服务器给我们返回的所有的数据
@Override
public void onResponse(Call c, Response r) throws IOException {
// 获取服务器返回的状态码
if (response.code() == 200) {
String result = response.body().string();
//通过Handle类给传值设置UI
//成功返回获取的数据
handler.obtainMessage(1, result).sendToTarget();
} else {
//不成功把状态码传进去
handler.obtainMessage(3, response.code()).sendToTarget();
}
}
// 当请求失败时call回调该方法(网络超时,IP地址写错)
@Override
public void onFailure(Call call, IOException e) {
//如果出现bug了就把异常信息传进去
handler.obtainMessage(3, e.toString()).sendToTarget();
}
});
```
5 通过what值来弹出不同的信息
//当数据发送完城,服务器会自动关闭
进度条
XML布局文件内:
- 属性:
- 设置样式:style //默认是圆形的
- 水平的样式:style=”?android:attr/progressBarStyleHorizontal”
- //参数的英文有点长,格式:?android:attr/progressBarStyle+样式
- 属性:
Android代码内:
.setMax(int)
- //设置进度条的最大值
- //可以理解成把进度条分成多少份
.setProgress(int)
- //设置当前进度
- //属于修改UI,【但是!】可以在子线程里修改
面试题:
什么是同步/异步?
- 同步就是单线程模式,代码一行一行去执行,第一行所有逻辑处理完了,才能执行第二行,如果第一行代码处理业务逻辑时间很长用了5000s,那么界面就会卡5000s钟再执行第二行。
- 异步就是多线程模式,不管第一行代码执行时间多长,第二行代码会照样执行,等第一行代码的逻辑处理完了会执行回调方法,在回调方法里面去处理业务逻辑。
问题:
忘记给布局设置添加图片,通过type值来匹配不同的返回不同的信息