Android_project

移动互联网开发技术

一、任务与要求

  1. 任务描述:开发一个班费日常使用记录的APP,记账员记录班费的收支情况,每笔支出需要包含日期、金额、购买的实物照片、购物小票(如果有)、实物的验收人。班级成员可以查看和查询班费的开支情况,可以在1周内(讨论期)对当笔开支提出质疑,班委成员回复质疑,所有质疑和应答全员可见。班级成员半数以上确认且所有质疑经发起人确认可以close的记录,可以标记为已确认状态,之后任何人无权再修改。超过讨论期未close的质疑自动close。

  2. 鼓励扩展的功能:记录归档、多班级支持。

  3. 前后端分离,鼓励使用区块链、跨端开发、云平台等新技术。

二、评分和验收标准

1.评分标准

课程考察环节、分值、评价细则与课程目标的对应关系

考察环节评价标准权重分值/100
优秀(90-100)良好(80-89)中等 (70-79)及格 (60-69)不及格 (<60)
方案 架构UI逻辑合理。 数据存储方案合理。 前端和后端的架构和逻辑合理。 后端有访问控制和角色控制和相关逻辑。UI逻辑合理。 数据存储方案合理。 前端和后端的架构和逻辑合理。 后端缺少访问控制和角色划分。但业务逻辑或控制逻辑有明显不合理的地方。UI逻辑合理。 数据存储方案合理。 后端提供了简单的访问接口,但缺少访问控制。UI逻辑合理。 数据存储方案合理。 后端提供了部分访问接口。UI逻辑一般。 数据没有远端控制。20
使用工具能够在实机和虚拟机上操作演示。 有版本控制。 使用开发工具和技术链配合较好。仅能在虚拟机上演示。 有版本控制。 使用了集成开发工具,但各工具配合紧密度一般。能在虚拟机上演示。 有版本控制。 使用了单一工具。能在虚拟机上演示。 无版本控制。 使用了单一工具。无法在虚拟机上演示。20
方法创新系统设计有独到见解或设计有较大创新,对课题有较深刻的分析和研究。系统设计有所创新,对课题有较正确的分析和研究。系统设计正确,论证严密,但见解不多。系统设计基本正确,论证基本清楚,但缺乏见解。系统设计不对,内容空泛,结构混乱。20
文档质量内容准确、完整,文字流畅,排版优美,设计方案内容详实充分。结合核心源代码说明方案的实现。内容比较准确、完整,文字比较流畅,排版比较优美,设计方案内容准确。 有源代码说明但对核心代码的把握有偏差。内容完整,无大的语法错误,有设计方案内容。 有源代码的copy但缺少说明。内容残缺不全,但基本能看懂,有一定的设计方案内容。 源代码缺少说明。逻辑混乱,无设计方案内容。 无法对代码给出说明。20
软件质量系统有一定的工作量,系统界面优美,软件功能完整,源程序代码规范、清晰、整洁,有较高的质量,无明显bug系统界面友好,源程序代码规范,软件质量较好,bug较少系统界面一般,源程序代码规范,软件质量一般,bug较多系统界面一般,软件质量一般,bug较多,功能基本实现软件设计能力差界面一般,软件质量较差,bug较多,功能没有实现20

三、报告内容

1 概述

1.1任务分解

系统分为三个功能角色:记账员、班委成员、班级成员,其主要职能如下:

1.记账员主要对日常的开支进行记录

2.班委成员主要对班级成员提出的质疑进行回复说明

3.班级成员主要对记账员记录的开支进行质疑,以及对班委成员的回复进行通过

1.2开发工具和工具的配合

使用的主要开发工具有IntelliJ IDEA2021(后端spring boot项目开发),Android Studio(前端app开发),Mysql(数据库),Navicat for Mysql,夜神模拟器,华为nova7手机(真机安装运行),腾讯云轻量服务器(后端云部署)

2 总体设计

2.1设计模式

​ 后端spring boot项目采用MVC设计模式如下图:

spring boot项目结构图

2.2Android核心组件

​ Recylerview、Glide(图片加载)、activity、fragment、Okthhp(实现客户端与服务器端通信)

3 详细设计

3.1spring boot属性配置

配置应用端口88,配置腾讯云服务器远端数据库及其密码,以及图片上传云端位置

server.port=**88
** spring.thymeleaf.cache=false
spring.datasource.name
=**spell-group-datasource
** spring.datasource.driverClassName=**com.mysql.cj.jdbc.Driver
** spring.datasource.url=**jdbc:mysql://49.233.46.138:3306/jilu?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true
** spring.datasource.username=**jilu
** spring.datasource.password=12345678

file.upload.path=/home/Android/upload

3.2Android Studio定义的部分API地址

下列举了腾讯云服务器url,图片存储url,注册,登录,图片上传,班费列表等API地址

public static String mainHost = “http://49.233.46.138:88“;
public static String mainImgHost = “http://49.233.46.138:88/public/getImg?path=“;
//注册
public static String regiestUrl = “/app/comments/registered”;
//登录
public static String loginUrl = “/app/comments/login”;
//图片上传
public static String photoUploadUrl = “/public/photoUpload”;

//班费列表

​ public static String listAllbanfeiInfoUrl = “/banfeiInfo/list”;

3.3云服务器配置

​ 1.开放端口88

 端口开放

2.配置服务器相关(jdk,tomcat,数据库等相关环境安装)

3.springboot打jar包上传并启动服务器端(有两种启动方式命令1. java -jar server.jar随终端启动2. nohup java -jar server.jar后台一直运行,为节约系统资源这里采用方式1)

云服务器终端启动服务器端

3.4相关功能设计(部分)

1.登录

后端(controller层)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 @ApiOperation(value = "登录", httpMethod = "POST", notes = "加载数据", response = ResponseData.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "UserAccount", value = "账号", required = false, paramType = "query", dataType = "string"),
@ApiImplicitParam(name = "UserPwd", value = "密码", required = false, paramType = "query", dataType = "string")
})
@RequestMapping("login")
public ResponseData listAll(@ApiIgnore String demoUserAccount, @ApiIgnore String demoUserPwd) {
try {
UserInfo user = userInfoMapper.getUserByAccount(demoUserAccount);
if (demoUserPwd.equals(user.getPassword())) {
return new ResponseData().data(user).success();
}
return new ResponseData().fail(10003, "用户名或密码错误");
} catch (Exception e) {
e.printStackTrace();
return new ResponseData().fail(10002, "用户不存在");
}
}

​ 前端

OkGo.get(Myapi.mainHost+Myapi.loginUrl)登录请求的接口

.params(“UserAccount”,uname)
.params(“UserPwd”,pwd)
参数:账号和密码

ToastUtils.showToast(LoginActivity.this,”登陆成功!”);

Intent intent3 = new Intent(LoginActivity.this,MainActivity.class);

startActivity(intent3)

当后端的@RequestParam中的值要和前端的params中的参数命名对应上,登录成功之后跳转到主页

2.注册

后端(controller层)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 @ApiOperation(value = "register", httpMethod = "POST", notes = "加载数据", response = UserInfo.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "userAccount", value = "手机号", required = false, paramType = "query", dataType = "string"),
@ApiImplicitParam(name = "userName", value = "姓名", required = false, paramType = "query", dataType = "string"),
@ApiImplicitParam(name = "userPwd", value = "密码", required = false, paramType = "query", dataType = "string"),
})
@RequestMapping("registered")
public ResponseData registered(String userAccount, String userPwd,String logo,String qianming,String phone) {
try {
UserInfo user = userInfoMapper.getUserByAccount(userAccount);
if (null == user) {
UserInfo demoUser = new UserInfo();
demoUser.setName(userAccount);
demoUser.setPassword(userPwd);
demoUser.setPhone(phone);

userInfoMapper.insertIgnoreNull(demoUser);
} else {
return new ResponseData().fail(10001, "账号已存在,请更换。");
}
} catch (Exception e) {
e.printStackTrace();
return new ResponseData().fail(500, e.getMessage());
}
return new ResponseData().success();
}

前端

OkGo.post(Myapi.mainHost+Myapi.regiestUrl)表示:网络请求地址

.params(“userAccount”,name)

.params(“userPwd”,pwd)

参数:姓名,密码

public void onSuccess(Responseresponse) {

表示请求响应的结果

if(code == 200){

​ ToastUtils.showToast(RegiestActivity.this,”注册成功!”);

​ finish();

​ }else {

​ ToastUtils.showToast(RegiestActivity.this,”注册失败!”);

​ }

这里判断响应的code值,如果是200提示注册成功,反之则提示注册失败

注意这里的注册默认为班级成员注册,因为是班级内部记账app,所以记账员及班委成员role需要在数据库内自行设置。

4.班费清单列表

后端(controller层)

1
2
3
4
5
6
7
8
9
10
11
@ApiOperation(value = "Read", httpMethod = "POST", notes = "加载数据", response = Result.class)
@RequestMapping("list")
public Result listAll() {
try {
List<BanfeiInfo> list = banfeiInfoMapper.listAll();
return ResultGenerator.genSuccessResult(list);
} catch (Exception e) {
e.printStackTrace();
return ResultGenerator.genErrorResult(500,e.getMessage());
}
}

前端

private void getAllData() {
OkGo.post(Myapi.mainHost+ Myapi.listAllbanfeiInfoUrl)
.execute(new StringCallback() {
@Override
public void onSuccess(Responseresponse) {
Log.e(“班费列表”,response.body());
BanFeiBean banFeiBean = JSONUtils.parserObject(response.body(),BanFeiBean.class);
int code = banFeiBean.getResultCode();

if(code == 200){

List<BanFeiBean.Data> data = banFeiBean.getData();
adapter = new BanFeiAdapter(BanweiActivity.this,R.layout.list_item_banfei,data);
recyclerView.setAdapter(adapter);
…}}

OkGo.post(Myapi.mainHost+ Myapi.listAllbanfeiInfoUrl)接口,无需传入参数,因为查询的是所有的班费列表通过Recyclerview控件展示列表

3.5技术难点

通过下载安装包,真机运行班费记录app(脱离usb限制),通过通过签名jks的方式实现。

4测试及出现过的问题及其解决方法

4.1测试界面

1.登录界面(三种身份选择)

登录界面

2.注册界面(仅可注册班级成员,记账员及班委为数据库设置)

注册界面

4.主页(记账员身份进入)

主页

5.记账员发布账单

记账

账单已更新

6.提出质疑

 班级成员发布质疑

质疑已公布

6.班委回复质疑

班委回复质疑

质疑已回复

8.班级成员通过质疑

班级半数以上确认

9.质疑人close质疑(未超过半数班级成员确认关闭无效)

质疑人close质疑

10.质疑已close

质疑已关闭

11.真机安装包下载及运行

真机安装包下载及运行

4.2出现的问题及解决方案

​ 1.Android Studio开发的客户端打Debug包手机无法安装

 安装失败

​ 解决方案:通过签名jks生成release包,最终实现apk打包安装

生成jks文件

​ 2.云服务器88端口无法访问(端口已开放)

​ 解决方案:查阅资料意识到可能是服务器内的系统放火墙未放通导致,使用systemctl stop firewalld 命令来进行关闭,最终解决问题。

5 总结

5.1全面总结

​ 本实践采用前后端分离模式开发,基于spring boot的服务器端,Android Studio的客户端实现项目功能。大体实现如下功能:

记账员:记录班费记录及验收人

班委:对班级成员的质疑进行回复

班级成员:对班费账单进行质疑(半数以上班级成员通过才能由质疑人close,或者超过讨论期未close的质疑自动close),通过班委的回复

在此基础上进行了云部署,成功将服务器端部署到腾讯云服务器上运行,此外客户端通过jks签名打release包安装到了真机运行。

本项目采用git进行版本控制,仓库地址如下:

https://github.com/ChengRui79/Android-charge-account.git

github仓库

5.2未完成的部分

​ 未完成的部分有:个人中心(对个人的注册信息及质疑,通过记录进行展示);多班级支持(可实现多个班级共同使用,即分班级对进行班费使用进行记录);记录归档功能

5.3收获

​ 对spring boot的mvc模式开发有了更熟练的掌握,通过前后端分离的采用,使我初步接触了Android客户端与IntelliJ IDEA服务器端基于Okthhp通信的主流网络通信框架。同时也在云平台技术的使用上更加深入(这是我在腾讯云上部署的第二个项目,第一个项目是一个java web项目)相对来说在本次部署难度大了很多,但同时也觉得收获颇丰。当然在前端设计上考虑略有不足,例如在用户注册页面,role显然不适合选择,由于前期分析不足,未考虑权限的特殊性,导致注册页面设计不合理,后删去role选择功能,默认班级成员。希望在以后的学习过程中多多接触新技术,不断提升能力。

6参考文献

[1] Android客户端连接服务器- OKHttp的简单实用方法[ED/OL]:https://blog.csdn.net/m0_47761892/article/details/107630036

[2] 如何把android studio中的项目发布到手机上(超详细版)[ED/OL]:https://blog.csdn.net/mlyhzt/article/details/126590913

[3] 详细SpringBoot教程之入门[ED/OL]:https://blog.csdn.net/DBC_121/article/details/104383089

[4] SpringBoot项目打包成jar包部署到宝塔面板(详细) [ED/OL]:https://blog.csdn.net/weixin_47390965/article/details/124666474

[5] 阿里云服务器配置及把java项目部署到服务器[ED/OL]:https://blog.csdn.net/weixin_45831807/article/details/121213809

[6] Spring Boot 接入[ED/OL]:https://cloud.tencent.com/document/product/1416/56031

[7] Android中Glide的使用[ED/OL]:https://blog.csdn.net/weixin_57542177/article/details/124074397?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167204971716782429745671%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167204971716782429745671&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-124074397-null-null.142


打赏支持
“我这么辛苦,请赏我点钱钱 o(*^ω^*)o”

Android_project
https://zcsry.cn/2023/04/02/Android-project/
作者
CR
发布于
2023年4月2日
更新于
2023年11月18日
许可协议