热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

手把手教你如何搭建一个自己的安卓快速开发框架之带你做自己的APP(二)

####点击查看上一篇文章:手把手教你如何搭建一个自己的安卓快速开发框架之BaseActivity(一)继上一篇我实现了基本的BaseActivity,

####点击查看上一篇文章:手把手教你如何搭建一个自己的安卓快速开发框架之BaseActivity(一)

继上一篇我实现了基本的BaseActivity,包含


  • ToolBar
  • 透明状态栏
  • 生命周期监控

那么,这一篇,我准备引入:


  • OkHttp 3.3.1(引用鸿洋的一个OkhttpUtil)
  • EventBus 3.0
  • Json解析
  • ButterKnife8.5.1

来完善我们的快速开发框架。

上次本来说这篇引入RXJava+retrofit,然后再引入MVP,但是突然发现过渡是不是有点太突然。
因此我准备循序渐进,慢慢深入,所以这次我们先用OKhttp+EventBus,去实现一次网络请求并完成界面异步更新。

####1、首先第一:明确我们服务返回的JSON数据格式:
我们暂且称为BaseData

{
"message": "ok",
"nu": "7700008953907",
"ischeck": "1",
"condition": "F00",
"com": "yunda",
"status": "200",
"state": "3",
"data": [
{
"time": "2017-02-14 19:14:27",
"ftime": "2017-02-14 19:14:27",
"context": "[陕西西安东郊区兴庆公园公司理工大分部]快件已被 已签收 签收",
"location": "陕西西安东郊区兴庆公园公司理工大分部"
},
{
"time": "2017-02-12 23:26:15",
"ftime": "2017-02-12 23:26:15",
"context": "[上海分拨中心]进行装车扫描,即将发往:陕西西安分拨中心",
"location": "上海分拨中心"
},
{
"time": "2017-02-12 23:21:52",
"ftime": "2017-02-12 23:21:52",
"context": "[上海分拨中心]在分拨中心进行称重扫描",
"location": "上海分拨中心"
},
]
}

####2、第二:我们有一个get请求的URL:
http://www.kuaidi100.com/query

有2个参数 type=yunda&postid=7700008953907。

####3、第三:
明确我们希望看到的请求方式:

Ok_Request.getAsyncData(this, map, UrlUtil.GetKuaiDi, new MyStringCallBack() {
@Override
public void onResponse(BaseData response, int id) {
List resultlist= null;
if (response != null) {
resultlist=response.getData();
}
//EventBus.getDefault().post(resultlist);
}

发送一次get请求,Map里面是我们需要提交的参数。 最后在onResponse方法中得到我们想要的返回结果response,它是通过BaseData做了一层封装的。

####4、第四:
请求结束,通过 EventBus.getDefault().post(resultlist);发送接收到的Json数据以供处理。并且通过dataEvent方法接收数据。ThreadMode.MAIN指定在主线程处理数据。

@Subscribe(threadMode = ThreadMode.MAIN)
public void dataEvent(List resultlist) {
tv.setText(resultlist.toString());
}

一次流程就这么走完了,但是从哪儿能看出我们这是一个框架呢?

1. BaseData

我们明确服务端的数据格式务必统一为BaseData,方便安卓端封装解析方法,直接返回需要的data字段。

2. getAsyncData

精简的请求方式,传入参数,URL,CallBack,在onresponse中处理结果即可。

3. BindView

所有界面省略繁琐的findviewById方法,采用ButterKnife注解生成,包括点击事件。

这里,第一和第三比较简单,第一点很必要,因为这直接决定了APP端的封装完整度和简洁度。第三点会用就行。所以,我们下来重点阐述第二点:

本来,OkhttpUtil的用法是这样的:

OkHttpUtils
.get()
.params(map)
.tag(mContext)
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
}
@Override
public void onResponse(String response, int id) {
}
});

直接放到Activity中有以下几个缺点:

  • 每个页面都得写这样一段。
  • 如果一个页面3个请求就得写三个这样的代码段。
  • 突然OKhttpUtil出Bug了需要修改为Volley,难道每个页面都要改吗?!

因此,我们需要做个封装:

/**
* Created by QHT on 2017-04-05.
*
* GET,PUT等网络操作类
*/
public class Ok_Request {
public static MediaType JSON = MediaType.parse("application/json;charset=utf-8");
/**
* GET方式
* 异步get请求
* @param url
*/
public static void getAsyncData(Context mContext, HashMap map,final String url, Callback callback) {
OkHttpUtils
.get()
.params(map)
.tag(mContext)
.url(url)
.build()
.execute(callback);
}
}

在Activity中调用Ok_Request.getAsyncData方法传入一个匿名CallBack即可。如下:

private static int Ok_count=2;
HashMap map &#61; new HashMap<>();
/**
* 参数
*/
map.put("type", "yunda");
map.put("postid", "7700008953907");
Ok_Request.getAsyncData(this, map, UrlUtil.GetKuaiDi, new MyStringCallBack() {
/**
* UI Thread
*/
&#64;Override
public void onBefore(Request request, int id) {
DialogUtil.showProgressDialog(MainActivity.this, true);
}
&#64;Override
public void onAfter(int id) {
--Ok_count;
if(Ok_count&#61;&#61;0){
DialogUtil.hideProgressDialog();
}
}
&#64;Override
public void onError(Call call, Exception e, int id) {
ToastUtil.showToastLong(e.getMessage());
}
&#64;Override
public void onResponse(BaseData response, int id) {
List resultlist&#61; null;
if (response !&#61; null) {
resultlist&#61;response.getData();
}
EventBus.getDefault().post(resultlist);
}
});

共四个回调方法onBefore&#xff0c;onAfter&#xff0c;onResponse&#xff0c;onError。

  • onBefore方法中我们显示一个dialog“加载中…”
  • onAfter方法中我们dismiss这个dialog
  • onResponse方法中处理服务端返回的数据
  • onError方法中进行异常处理

如上&#xff0c;我们已经完成了我们的网络请求。但是&#xff0c;如果我们一个页面不止一次请求呢&#xff0c;有两次呢&#xff1f;我们怎么控制dialog何时隐藏&#xff1f;

这个时候&#xff0c;我们就需要一个计数器Ok_count&#xff0c;在onAfter方法中执行Ok_count减一&#xff0c;并且判断Ok_count是否为0&#xff0c;若为0才允许隐藏dialog。(类似于同步计数器CountDownLatch类)

####说完了请求&#xff0c;下来我们来说说Json

默认情况下&#xff0c;Okhttp返回的数据为Response&#xff0c;那么我们就来一步一步写自己的解析方式&#xff1a;

请求结束之后&#xff0c;数据层首先执行parseNetworkResponse方法(此方法运行在子线程)&#xff0c;返回一个Response&#xff0c;在这里&#xff0c;我们对需要的数据进行处理&#xff1a;

/**
* Created by QHT on 2017-04-05.
*/
public abstract class MyStringCallBack extends Callback{
/**
* Thread Pool Thread
* &#64;param response
* &#64;param id
*/
&#64;Override
public BaseData parseNetworkResponse(Response response, int id) throws Exception {
String temp&#61;response.body().string();
BaseData baseData &#61; GsonUtils.jsonToModel(temp, BaseData.class);
return baseData;
}
}

解析的代码如下&#xff1a;

public static T jsonToModel(String json,Class clazz) {
if (TextUtils.isEmpty(json) || null &#61;&#61; clazz) {
return null;
}
try {
return gson.fromJson(json, clazz);
}catch (Exception e){
e.printStackTrace();
LogUtil.e("服务端接口json数据格式异常:"&#43;e.getMessage());
return null;
}

  • 通过response.body().string()可以拿到返回的String。
  • 通过我们写好的Json解析类可以将String解析为我们最外层的BaseData。
  • 固定服务端返回数据格式的重要作用就在这儿(统一处理)

接下来&#xff0c;回调onResponse方法&#xff0c;参数为我们上面返回的BaseData&#xff0c;onResponse方法最后就变成了这样&#xff1a;

&#64;Override
public void onResponse(BaseData response, int id) {
List resultlist&#61; null;
if (response !&#61; null) {
resultlist&#61;response.getData();
}
EventBus.getDefault().post(resultlist);
}

要什么&#xff0c;在BaseData 中取什么就行。

下一篇&#xff0c;我准备开始完善功能了&#xff0c;加入&#xff1a;

  1. BaseFrament
  2. 微信底部4按钮切换
  3. 登录功能
  4. 快递追踪功能

最后&#xff0c;我将代码上传到github上&#xff0c;持续更新&#xff0c;逐渐完善这个简易框架。

我的QQ: 1003077897
我的csdn&#xff1a;http://blog.csdn.net/u012534831
我的github&#xff1a;https://github.com/qht1003077897
我的个人博客&#xff1a;https://qht1003077897.github.io


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 注意:以下分析都是基于Retrofit2转载请注明出处:http:blog.csdn.netevan_manarticledetails51320637本节是《Retrofit的使 ... [详细]
  • Retrofit+Rxjava+OkHttp
    为什么80%的码农都做不了架构师?参考:http:duanyytop.github.io20160806Retrofit%E7%94%A8%E6% ... [详细]
  • 本篇文章给大家分享的是有关静态方法如何在Kotlin项目中实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • 美团Android 岗3次挂了,这次终于成功拿下!
    美团Android岗3次挂了,这次终于成功拿下!-面试流程自我介绍回答问题————(详情看下面的攻略)前面会问你很多技术问题,从简单到难,直到问到你打不出来就会又问其他部分的,也是 ... [详细]
  • android之OkHttpClient通信OkHttpClient用法1:自定义缓存OkHttpClienthttpclientnewOkHttpClient.Builder() ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
author-avatar
天生骄傲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有