从零开始搭建一个联网小程序(三)—— Android端程序

文章列表

  1. 从零开始搭建一个联网Android APP(一)—— 工具和基本概念介绍
  2. 从零开始搭建一个联网Android APP(二)—— 服务器端程序
  3. 从零开始搭建一个联网Android APP(三)—— Android端程序

本文源码

注:该工程有两个branch,master为离线版本,所有功能集成到Android端,便于使用;online为在线版本,适合喜欢折腾的人

注:本系列博客主要重点在于服务器端的程序开发、部署和Android端如何与服务器端通信,不涉及具体的Android开发内容。


程序编写

  这里主要描述Android端如何与server进行通信并解析返回的Json格式数据。主要涉及两个主要的库文件:

  1. okhttp3 —— 用于与server通信
  2. GSON —— 用于解析Json格式数据

与Server通信

网络请求代码如下:

// GET
public static void sendRequestGetAsy(String address, okhttp3.Callback callback){
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
            .url(BASE_URL + address)
            .build();
    client.newCall(request).enqueue(callback);
}

// POST
public static void addNewAccount(Account account, okhttp3.Callback callback){
    OkHttpClient client = new OkHttpClient();
    RequestBody requestBody = new FormBody.Builder()
            .add("content", account.getContent())
            .add("number", String.format(Locale.CHINA, "%.2f", account.getNumber()))
            .add("person", account.getPerson())
            .add("createTime", account.getCreateTime())
            .build();
    Request request = new Request.Builder()
            .url(BASE_URL + ADD_ACCOUNT)
            .post(requestBody)
            .build();
    client.newCall(request).enqueue(callback);
}

与server对应,这里也有GET和POST两种方式,GET方式就将参数全部写到address里面传进来就好,POST方式采用键值对的形式将参数添加到body里面。同时为了不阻塞现成,这里都采用异步的方式调用网络请求。

调用方式如下:

GET

private void getAccountInfo(){
    String str = HttpUtils.QUERY_ALL_ACCOUNT + OFFSET + "/" + LIMIT;
    HttpUtils.sendRequestGetAsy(str, new okhttp3.Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            Log.e(TAG, e.toString());
            runOnUiThread(() -> {
                swipeRefreshLayout.setRefreshing(false);
                showToast("获取账单信息失败,请检查网络连接...");
            });
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            try{
                assert response.body() != null;
                String str = response.body().string();
                JSONObject jsonObject = new JSONObject(str);
                //子线程不能更新UI相关内容
                updateAccountUI((ArrayList<Account>)
                        HttpUtils.parseAllAccount(jsonObject.getString(ACCOUNTS_INFO)));
                if (isRefresh){
                    runOnUiThread(() -> {
                        swipeRefreshLayout.setRefreshing(false);
                        isRefresh = false;
                        new Handler().postDelayed(() -> showToast("数据更新完毕"), 300);
                    });
                }
            }catch (JSONException e){
                Log.e(TAG, e.toString());
            }
        }
    });
}

POST

这里直接传入一个自定义类的实例。

解析Json数据

在回调函数内,通过这句话String str = response.body().string();就可以取出服务器返回的数据内容。具体解析过程如下:

定义一个订单类,然后利用GSON提供的注解函数,标明每个字段对应的json函数键值是什么,然后就可以用GSON自动解析了。

package com.example.account_book;

import com.example.account_book.util.TimeUtils;
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class Account implements Serializable, Comparable<Account>{

    @SerializedName("_account_id")
    private int id;
    @SerializedName("_content")
    private String content;
    @SerializedName("_number")
    private double number;
    @SerializedName("_person")
    private String person;
    @SerializedName("_create_time")
    private String createTime;

    public Account(){
        this.content = "";
        this.number = 0.0;
        this.person = "xkw";
        this.createTime = TimeUtils.now();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public double getNumber() {
        return number;
    }

    public void setNumber(double number) {
        this.number = number;
    }

    public String getPerson() {
        return person;
    }

    public void setPerson(String person) {
        this.person = person;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Time: " + this.createTime + "\n" +
                "Content: " + this.content + "\n" +
                "Number: " + this.number + "\n" +
                "Person: " + this.person;
    }

    public String getSimpleString() {
        return this.createTime + this.content + this.number + this.person;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Account){
            Account account = (Account)obj;
            return this.createTime.equals(account.getCreateTime());
        }
        return false;
    }

    @Override
    public int compareTo(Account account) {
        return this.createTime.compareTo(account.createTime);
    }
}

GSON自动解析

public static List<Account> parseAllAccount(String jsonData){
    //使得可以解析Date型变量
    Gson gson = new GsonBuilder().setDateFormat(DATE_FORMAT).create();
    return gson.fromJson(jsonData, new TypeToken<List<Account>>(){}.getType());
}

public static Account parseAccountDetail(String jsonData){
    //使得可以解析Date型变量
    Gson gson = new GsonBuilder().setDateFormat(DATE_FORMAT).create();
    return gson.fromJson(jsonData, Account.class);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值