到这里我们将正式搭建我们的网络请求框架,来实现与后台的交互,将前端与后台真正的连接起来。还没有做好准备工作的小伙伴可以阅读之前的两篇文章TextInputLayout实现登录界面和LitePal初始化本地数据库,来完成自己的准备工作。话不多说,来看一下今天的内容吧~
OkHttp是Square公司的一款优秀的HTTP框架,它支持get请求和post请求,支持基于Http的文件上传和下载,支持加载图片,无缝的支持GZIP来减少数据流量,支持响应缓存避免重复的网络请求,支持使用连接池来降低响应延迟问题。
OkHttp 官方网址:http://square.github.io/okhttp/
OkHttp GitHub地址:https://github.com/square/okhttp
使用前配置:
(1)对于Android Studio的用户,可以选择添加:compile 'com.squareup.okhttp3:okhttp:3.8.1'
(2)Eclipse的用户,可以下载最新的 the latest JAR ,添加依赖就可以用了
注:okhttp内部依赖okio,别忘了同时导入okiocompile 'com.squareup.okio:okio:1.13.0'
最新的okio jar地址 the latest JAR
Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。
添加依赖:Gson使用配置注: 安装插件GsonFormat快速实现JavaBean
1).Android studio File->Settings..->Plugins–>Browse repositores..搜索GsonFormat
2).安装插件,重启android studio
使用GsonFormat快速生成javaBean
1.采用单例模式创建OkHttpManager对象
* 获取当前实例对象,确保唯一
* @return
*/
public static OkHttpManager getInstance(){
if (instance==null){
synchronized (OkHttpManager.class){
if (instance==null){
instance=new OkHttpManager();
}
}
}
return instance;
}
2.创建OkHttpClient对
public OkHttpManager(){
//声明Handler对象,指定为主线程Looper,确保执行方法在主线程中
mHandler=new Handler(Looper.getMainLooper());
//指定超时时间等参数
OkHttpClient.Builder builder=new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(15,TimeUnit.SECONDS);
mOkHttpClient=builder.build();
}
3.封装GET、POST请求方法
* get请求
*
* @param url
* @param resultCallback
*/
public void getNet(String url,ResultCallback resultCallback){
Request request=new Request.Builder()
.url(url)
.method("GET",null)
.build();
dealNet(request,resultCallback);
}
/**
* post请求
*
* @param url
* @param resultCallback
* @param param 传入参数,数量不定
*/
public void postNet(String url,ResultCallback resultCallback,Param ...param){
if (param==null){
param=new Param[0];
}
FormBody.Builder formBody= new FormBody.Builder();
for (Param p:param){
formBody.add(p.key,p.value);
}
RequestBody requestBody=formBody.build();
Request request=new Request.Builder()
.url(url)
.post(requestBody)//传入构建好的参数
.build();
dealNet(request,resultCallback);
}
4.定义网络请求监听接口,执行网络请求操作
/**
* 发送网络请求
* @param request
* @param resultCallback 自己定义的监听回调
*/
private void dealNet(final Request request, final ResultCallback resultCallback) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, final IOException e) {
mHandler.post(new Runnable() {
@Override public void run() {
//失败时执行的方法
resultCallback.onFailed(resultCallback,e);
}
});
}
@Override public void onResponse(Call call, Response response) throws IOException {
String str="";
try {
str = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
final String finalStr=str;
Log.i("OkHttpManager", "onResponse: " + finalStr);
mHandler.post(new Runnable() {
@Override public void run() {
//成功时执行的方法
resultCallback.success(finalStr);
}
});
}
});
}
public static abstract class ResultCallback{
public abstract void onFailed(ResultCallback callback,Exception ex);
public abstract void success(String response);
}
1.首次登录验证,先来看一下登陆逻辑:
根据查找数据库中的user表,查看是否有当前用户信息存在,因为用户表只保存当前用户,有数据则跳过登录,无数据则进行登录。
//判断是否是首次登录
if (chekLogin()) {
//非首次登录逻辑
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
} else {
//首次登录逻辑
initStatusBar();
initViews();
}
/**
* 验证是否是首次登录
*/
private boolean chekLogin() {
List list = new ArrayList<>();
list = DataSupport.findAll(User.class);
if (null != list && list.size() > 0) {
//数据库user表不为空,已经登录,返回true
return true;
}
return false;
}
2.登录逻辑实现
/**
* 登录
*/
private void login() {
//校验数据是否为空等,如果数据不和要求直接提示,避免发送错误数据到后台
if (checkData()) {
//显示登录加载界面
mRelLoading.setVisibility(View.VISIBLE);
//发送登录请求,网络验证
OkHttpManager.getInstance().postNet(Constants.loginApi,
new OkHttpManager.ResultCallback() {
@Override
public void onFailed(OkHttpManager.ResultCallback callback, Exception ex) {
mRelLoading.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "服务连接异常,登录失败", Toast.LENGTH_SHORT).show();
}
@Override public void success(String response) {
LoginBeanResult loginBeanResult=getDataFromJson(response);
mRelLoading.setVisibility(View.GONE);
if (loginBeanResult.getCode()==0){
SharePreUtil.SetShareString(mContext,"userid",loginBeanResult.getBody().getUserid());
DataSupport.deleteAll(User.class);
User user=new User();
user.setUserId(loginBeanResult.getBody().getUserid());
user.setNickName(loginBeanResult.getBody().getNickname());
user.setSex(loginBeanResult.getBody().getSex());
user.setJob(loginBeanResult.getBody().getJob());
user.setArea(loginBeanResult.getBody().getArea());
user.setPhoneNum(loginBeanResult.getBody().getPhonenum());
user.setImg(loginBeanResult.getBody().getImg());
//保存数据到数据库中
user.save();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
} else {
Toast.makeText(getApplicationContext(), "用户名或密码错误,登录失败", Toast.LENGTH_SHORT).show();
}
}
},new OkHttpManager.Param("userid",mUserName),new OkHttpManager.Param("password",mPassWord));
}
}
3.Gson数据解析
/**
* 解析json数据
* @param response
* @return
*/
private LoginBeanResult getDataFromJson(String response) {
Gson gson=new Gson();
LoginBeanResult result=gson.fromJson(response,LoginBeanResult.class);
return result;
}
注释:在请求网络时,别忘了添加网络权限
到这里,Okhttp的封装和登录验证逻辑就完成了,看一下实现效果吧~
福利社区:
今天给大家介绍几个涨姿势的工具:
在线解析json: http://www.jsoneditoronline.org/
在线解析json为JavaBean: http://www.jsonschema2pojo.org/
在线生成shape: http://shapes.softartstudio.com/
资料源码,请戳这里~