android安卓看点新闻课设

news2024/9/26 5:24:08

一、系统需求分析

1.1 引言

1.1.1 开发目的

看点新闻App的开发是为了实时查看最新消息以了解社会动态,增长知识,增广见闻,顺便娱乐一下内心世界来放松自己。

1.1.2 开发背景

随着新媒体的崛起,纸媒遭受到重大打击,纸媒发展之路愈走愈窄,面临着前所未有的挑战。由于互联网的发展,人们获得信息的来源越来越多。为了满足人们对信息的渴望追求,各种类型的新闻App层出不穷,新闻App凭借其丰富的资讯资源,实时的信息推送和方便的社交互动被越来越多的用户认可。其具有许多报纸所没有的优势,它所提供的新闻信息打破了读报所需的线性时间和空间模式,慢慢改变了受众对世界的认识习惯。因此,开发一个新闻App显得尤其重要!

1.2 项目概述

1.2.1 产品功能描述

看点新闻App是基于Android Studio编辑器上开发的一款可以查看、添加、删除新闻,登录,编辑个人资料,查看个人收藏,清除缓存的安卓App。

1.2.2 运行环境

   操作系统:Window10
   开发工具:Android Studio 3.4.1
   数据库:LitePal,mysql
   硬件环境:

CPU:Intel® Core™i5-7200U CPU @ 2.50GHz 2.71 GHz
内存:12.0GB

1.3 系统功能描述

1.3.1 基本描述

看点新闻App通过获取互联网专业数据科技服务商—聚合数据的新闻接口来实现新闻数据的展示。由于每日限制100次请求,故每次请求时就缓存新闻数据到本地数据库中。当每次下拉刷新就分页查询10条新闻数据重新显示在对应的tab碎片中。用户可以根据自己的兴趣点击对应的tab标签来阅读新闻,清除本地缓存,登录后(取消)收藏新闻,查看个人收藏,添加、查看、删除个人发布的文章等。

1.3.2 系统功能描述

登录、注册模块:注册过的用户登录后才能(取消)收藏新闻,查看个人收藏,添加、查看、删除个人发布的文章等。
个人信息模块:用户登录后可以查看、修改个人资料。
个人文章模块:用户登录后可以发布、查看、删除文章。
个人收藏模块:用户登录后可以(取消)收藏新闻接口数据子项,并且查看自己收藏的所有新闻。
清除缓存模块:该功能主要清除浏览网页时在本地留下的离线内容和图片缓存。
展示新闻列表模块:该功能主要在用户打开App时,就请求聚合数据提供的新闻接口来显示在tab页面并将请求的数据缓存到本地数据库中。若当日请求次数已用完,则分页查询本地数据库。

二、系统总体设计

2.1 系统整体结构

系统结构图
在这里插入图片描述

2.2 数据存储设计

用户表:
字段名 数据类型 长度 是否为null 字段描述
userAccount varchar 20 否 账号
nickname varchar 20 是 昵称
userPwd varchar 20 否 登录密码
userSex varchar 6 是 性别
userBirthDay varchar 20 是 生日
userSignature varchar 50 是 个性签名
imagePath varchar 50 是 保存头像的路径
新闻表:
字段名 数据类型 长度 是否为null 字段描述
reason varchar 20 否 数据响应理由
result varchar 20 否 结果集
stat int 4 否 响应状态
uniquekey varchar 100 否 新闻id
title varchar 100 否 新闻标题
date varchar 50 否 请求日期
category varchar 10 否 新闻标签
author_name varchar 30 否 新闻作者
url varchar 200 否 新闻链接
thumbnail_pic_s varchar 200 否 附图1的地址
thumbnail_pic_s02 varchar 200 否 附图2的地址
thumbnail_pic_s03 varchar 200 否 附图3的地址
新闻收藏表:
字段名 数据类型 长度 是否为null 字段描述
userIdNumer varchar 20 否 用户账号
newsId varchar 100 否 新闻id
newSTitle varchar 100 否 新闻标题
newsUrl varchar 200 否 新闻链接
个人文章表:
字段名 数据类型 长度 是否为null 字段描述
userId varchar 20 否 用户账号
articleTitle Varchar 50 否 文章标题
articleAuthor varchar 20 否 用户昵称
articleTime varchar 50 否 发布时间
articleImagePath varchar 100 是 文章图片地址
articleContent varchar 100 否 文章内容

三、系统详细设计

3.1 登录、注册功能

(1) 用户第一次启动App时,可以查看新闻列表和具体的新闻内容,但是不能查看和编辑个人资料,(取消)收藏一条新闻内容,查看个人收藏和我的文章等。只有用户登录后才可实现这些被限制的功能。
(2) 当用户没有账号时,他可以选择注册并登录使用。注册过程中,因为LitePal数据库底层已内置了一个索引,所以我将用户账号设置为唯一标识的字段。若有用户输入相同的账号,系统将提醒用户重新输入账号。当输入密码和确认密码相同即可注册成功!注意,以上所有输入均不为空。

3.2 编辑资料功能

用户登录后点击编辑资料时,其根据需要修改对应的信息后,点击左上角的返回按钮,再点击主界面的抽屉弹出按钮,即可看到刚才修改的个人信息。

3.3 个人收藏功能

用户登录后在主界面新闻列表中点击某个新闻子项后进入webview展示新闻内容,点击右下角的收藏按钮即可进行收藏,再次点击则取消收藏!回到主界面后,点击左上角抽屉按钮弹出导航,点击个人收藏即可看到刚才收藏的新闻标题。

3.4 文章管理功能

用户登录后在主界面点击左上角的按钮,弹出抽屉导航栏,点击”我的文章”即可查看自己发布的新闻列表,点击右下角的悬浮按钮即可进入编辑文章的界面。在编辑文章界面输入文章标题和内容,同时可以添加显示文章的一张图片。点击发布按钮之后返回到“我的文章”界面即可看到刚才添加的文章!点击某个卡片即可查看该文章的具体内容。在文章详情界面,可以点击红色垃圾箱按钮删除该文章!

3.5 清除缓存功能

用户点击某个新闻子项进入浏览时,新闻内容和图片将会缓存到本地,此时用户可以在抽屉导航中点击“清除缓存”即可清除本地缓存。

四、系统实现

4.1 登录、注册功能

在这里插入图片描述

在这里插入图片描述

4.2 编辑资料功能

在这里插入图片描述
在这里插入图片描述

4.3 个人收藏功能

在这里插入图片描述
在这里插入图片描述

4.4 文章管理功能

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.5 清除缓存功能

在这里插入图片描述
在这里插入图片描述

4.6 部分主要代码

4.6.1异步消息处理机制来填充新闻列表

private void getDataFromNet(final String data) {
    @SuppressLint("StaticFieldLeak")
    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
        //子线程
        @Override //储备key:547ee75ef186fc55a8f015e38dcfdb9a
        protected String doInBackground(Void... params) { // 自己的key:af2d37d2ed31f7a074f1d49b5460a0b5,可以替换下面请求中的key
            String path = "http://v.juhe.cn/toutiao/index?type=" + data + "&key=af2d37d2ed31f7a074f1d49b5460a0b5";
            URL url = null;
            try {
                url = new URL(path);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                //设置请求方式
                connection.setRequestMethod("GET");
                //设置读取超时的毫秒数
                connection.setReadTimeout(5000);
                //设置连接超时时间
                connection.setConnectTimeout(5000);
                //获取状态码
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) { // 200
                    //获取服务器返回的输入流
                    InputStream inputStream = connection.getInputStream();
                    String json = streamToString(inputStream, "utf-8");
                    //返回任务的执行结果
                    return json;
                } else {
                    //返回的状态码不是200
                    System.out.println(responseCode);
                    return 404 + data;
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (ProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return 404 + data;
        }
//当给后台任务执行完毕并通过return语句返回时,此方法将被调用,返回来的数据可以进行一些UI操作,并将处理的参数传入
        protected void onPostExecute(final String result) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //查看状态码是否为200,若不是(开子线程),然后从本地加载相应的数据
                    NewsBean newsBean = null;
                    //不包括endIndex
                    Log.d("后台处理的数据为:", "run: " + result);
                    if (!result.substring(0, 3).equals("404")) {
                        newsBean = new Gson().fromJson(result, NewsBean.class);
                        System.out.println(newsBean.getError_code());
                        if ("0".equals("" + newsBean.getError_code())) {
                            //obtainmessage()方法是从消息池中拿来一个msg,不需要另开辟空间new,new需要重新申请,效率低,obtianmessage可以循环利用;
                            Message msg = newsHandler.obtainMessage();
                            msg.what = UPNEWS_INSERT;
                            msg.obj = newsBean;
                            //发送一个通知来填充数据,因为安卓不允许在子线程中进行UI操作
                            newsHandler.sendMessage(msg);
                        } else {
                            //{"resultcode":"112","reason":"超过每日可允许请求次数!","result":null,"error_code":10012}
                            //实现从数据库加载数据
                            Log.d("超过请求次数或者其他原因", "run: 现在从本地数据库中获取");
                            Log.d("当前tab名字为:", "run: " + currentTabName);
                            threadLoaderData(currentTabName);
                        }
                    } else {
                        threadLoaderData(result.substring(3));
                    }
                }
            }).start();
        }

        //当后台任务中调用了publishProgress(Progress...)方法后,onProgressUpdate方法很快被执行
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    };
    //启动异步加载任务
    task.execute();
}

4.6.2加载数据,实现从本地数据库中读取数据刷新到newsListView的适配器中,其中用到了分页查询和多线程

private void threadLoaderData(final String category) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                //沉睡1.5s,本地刷新很快,以防看不到刷新效果
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //若快速点击tab,则会出现getActivity()为空的情况,但是第一次加载肯定不会出错,所以将要拦截,以防app崩溃
            if (getActivity() == null)
                return;
            //此处的用法:runOnUiThread必须是在主线程中调用,getActivity()获取主线程所在的活动,切换子线程到主线程
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //重新生成数据,传入tab条目
                    loaderRefreshData(category);
                    //表示刷新事件结束,并隐藏刷新进度条
                    swipeRefreshLayout.setRefreshing(false);
                }
            });
        }
    }).start();
}
private void loaderRefreshData(final String category) {
    //top,shehui,guonei,guoji,yule,tiyu,junshi,keji,caijing,shishang
    String categoryName = "头条";
    if (category.equals("top")) {
        categoryName = "头条";
    } else if (category.equals("shehui")) {
        categoryName = "社会";
    } else if (category.equals("guonei")) {
        categoryName = "国内";
    } else if (category.equals("guoji")) {
        categoryName = "国际";
    } else if (category.equals("yule")) {
        categoryName = "娱乐";
    } else if (category.equals("tiyu")) {
        categoryName = "体育";
    } else if (category.equals("junshi")) {
        categoryName = "军事";
    } else if (category.equals("keji")) {
        categoryName = "科技";
    } else if (category.equals("caijing")) {
        categoryName = "财经";
    } else if (category.equals("shishang")) {
        categoryName = "时尚";
    }
    //页数加1
    ++pageNo;
    List<NewsBean.ResultBean.DataBean> dataBeanList = new ArrayList<>();
    NewsBean.ResultBean.DataBean bean = null;
    int offsetV = (pageNo - 1) * pageSize;
    Log.d("pageNo", "页数为: " + pageNo);
    Log.d("offsetV", "偏移量为: " + offsetV);
    Log.d("offsetV", "以下开始查询");
    List<NewsInfoBean> beanList = LitePal.where("category = ?", categoryName).limit(pageSize).offset(offsetV).find(NewsInfoBean.class);
    Log.d("TAG", "查询的数量为:" + beanList.size());
    //若查询的结果为0,则重新定位页数为1
    if (beanList.size() == 0) {
        pageNo = 1;
        offsetV = (pageNo - 1) * pageSize;
        beanList = LitePal.where("category = ?", categoryName).limit(pageSize).offset(offsetV).find(NewsInfoBean.class);
        Log.d("分页查询", "loaderRefreshData: 已经超过最大页数,归零并重新查询!");
    }
    Log.d("刷新查到的数据大小", "run: " + beanList.size());
    for (int i = 0, len = beanList.size(); i < len; ++i) {
        bean = new NewsBean.ResultBean.DataBean();
        bean.setDataBean(beanList.get(i));
        dataBeanList.add(bean);
        Log.d("刷新id:", "run: " + beanList.get(i));
    }
    contentItems = dataBeanList;
    //将dataBeanList赋值给全局的contentItems,否则点击新闻子项会出错,并且contentItems之前要清空,不然起不到更新视图的作用
    TabAdapter adapter = new TabAdapter(getActivity(), contentItems);
    newsListView.setAdapter(adapter);
    //当adapter中的数据被更改后必须马上调用notifyDataSetChanged予以更新。
    adapter.notifyDataSetChanged();
}
}

五、联系与交流

q:969060742 完整代码、报告、apk

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1551434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode安装vue3+elment-plus

1.用vscode打开打算创建项目的目录 2.命令行中运行以下命令 npm create vuelatest3.设置好项目名称 4.执行以下命令 cd <your-project-name>5.执行以下命令 cnpm install6.执行以下命令安装elment-plus cnpm install element-plus --save7.执行以下命令 npm run dev…

Vuepress 2从0-1保姆级进阶教程——美化与模板

Vuepress 2 专栏目录 1. 入门阶段 Vuepress 2从0-1保姆级入门教程——环境配置篇Vuepress 2从0-1保姆级入门教程——安装流程篇Vuepress 2从0-1保姆级入门教程——文档配置篇Vuepress 2从0-1保姆级入门教程——范例与部署 2.进阶阶段 Vuepress 2从0-1保姆级进阶教程——全文搜索…

使用unplugin-auto-import页面不引入api飘红

解决方案&#xff1a;. tsconfig.json文件夹加上 {"compilerOptions": {"target": "ES2020","useDefineForClassFields": true,"module": "ESNext","lib": ["ES2020", "DOM", &q…

Python程序设计 循环结构(二)

1.斐波那契数列 编写一个能计算斐波那契数列中第x个数的小程序。斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、 因数学家莱昂纳多斐波那契&#xff08;Leonardoda Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为…

分类任务中的评估指标:Accuracy、Precision、Recall、F1

概念理解 T P TP TP、 T N TN TN、 F P FP FP、 F N FN FN精度/正确率&#xff08; A c c u r a c y Accuracy Accuracy&#xff09; 二分类查准率 P r e c i s i o n Precision Precision&#xff0c;查全率 R e c a l l Recall Recall 和 F 1 − s c o r e F1-score F1−s…

Collection与数据结构 数据结构预备知识(一) :集合框架与时间空间复杂度

1.集合框架 1.1 什么是集合框架 Java集合框架,又被称为容器,是定义在java.util包下的一组接口和接口实现的一些类.其主要的表现就是把一些数据放入这些容器中,对数据进行便捷的存储,检索,管理.集合框架底层实现原理其实就是各种数据结构的实现方法,所以在以后的学习中,我们会…

2024年2月吸尘器行业线上电商(京东天猫淘宝)综合排行榜

鲸参谋监测的线上电商平台&#xff08;淘宝天猫京东&#xff09;2月吸尘器行业销售数据公开。 根据鲸参谋电商数据平台显示&#xff0c;吸尘器行业2月销量累计约53万件&#xff0c;环比上个月下滑29%&#xff0c;同比去年下滑19%&#xff1b;销售额累计约4亿&#xff0c;环比上…

​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结

接上次博客&#xff1a;Redis&#xff08;四&#xff09;&#xff1a;持久化和事务&#xff1a;RDB&#xff08;定期备份&#xff09;【触发机制、流程说明、文件的处理、优缺点】、AOF&#xff08;实时备份&#xff09;【使用AOF、命令写入、文件同步、重写机制、启动时数据恢…

Karmada 管理有状态应用 Xline 的早期探索与实践

背景与动机 目前随着云原生技术和云市场的不断成熟&#xff0c;越来越多的 IT 厂商开始投入到跨云多集群的怀抱当中。以下是 flexera 在 2023 年中关于云原生市场对多云多集群管理的接受程度的调查报告&#xff08;http://info.flexera.com&#xff09; 从 flexera 的报告中可…

学习或复习电路的game推荐:nandgame(NAND与非门游戏)、Turing_Complete(图灵完备)、logisim工具

https://www.nandgame.com/ 免费 https://store.steampowered.com/app/1444480/Turing_Complete/ 收费&#xff0c;70元。据说可以导出 Verilog &#xff01; logisim及其衍生版本 都需要安装java环境。 http://www.cburch.com/logisim/ 是原版&#xff0c; 下载页面&#…

Python实现猜数字游戏:一次编程旅程

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Nexus3 Docker 私有仓库

Nexus3 Docker 私有仓库 安装并部署 Nexus3 $ docker search nexus3$ docker pull sonatype/nexus3$ mkdir /home/tester/data/docker/nexus3/sonatype-work $ sudo chown -R 200 /home/tester/data/docker/nexus3/sonatype-work$ docker run -d --namenexus3 \ --restartalw…

【CSS浮动属性】别再纠结布局了!一文带你玩转CSS Float属性

在网页设计的世界里&#xff0c;CSS浮动属性&#xff08;float&#xff09;就像一把双刃剑。它能够让元素脱离文档流&#xff0c;实现灵活的布局&#xff0c;但如果处理不当&#xff0c;也可能引发一系列布局问题。 今天&#xff0c;我们就来深入探讨这把“剑”的正确使用方法…

T1 神奇苹果桶 (25分) - 小米前端笔试编程题解

考试平台&#xff1a; 赛码 题目类型&#xff1a; 20道选择 2道编程题 考试时间&#xff1a; 2024-03-23 &#xff08;两小时&#xff09; 题目描述 小希在森林冒险的时候发现一个神奇的木桶&#xff0c;某些时会凭空出现一些苹果&#xff0c;小希很解地大家分享了这一个神奇…

argocd cli工具使用

一、前言 ragocd除了使用web界面操作之外&#xff0c;也可以通过argocd cli工具进行操作&#xff0c;关于集群创建、gitlab仓库创建、app创建都是可以通过yaml 文件去操作&#xff0c;使用web界面创建的操作也需要使用argocd cli工具进行备份 二、使用 在argocd部署的章节已经…

fuzzywuzzy,一个好用的 Python 库!

目录 前言 安装 基本功能 1. 字符串相似度比较 2. 模糊匹配与排序 实际应用场景 1. 数据清洗 2. 文本匹配与搜索 3. 搜索引擎优化 总结 前言 大家好&#xff0c;今天为大家分享一个好用的 Python 库 - fuzzywuzzy Github地址&#xff1a;https://github.com/seatgeek/fu…

nginx 不能访问的排查思路

场景: 在云主机上搭建了nginx服务&#xff0c;测试阶段nginx服务监听的81端口&#xff0c;但无法通过公网访问到nginx默认网页&#xff1b; Nginx安装路径&#xff1a;/www/nginx/ 尝试访问&#xff0c;发现81端口不通 允许访问81 允许81端口开放后&#xff0c;发现 于是查看n…

蓝鹏为何专注智能测量仪的加工定制?

在这个日新月异的科技时代&#xff0c;自动化工厂层出不穷&#xff0c;并且是在不断地升级改造&#xff0c;为了产品的高速高质高效的自动化生产&#xff0c;智能测量仪的重要性不言而喻。智能测量仪的种类很多&#xff0c;蓝鹏一直致力于专业仪器定制&#xff0c;但你有没有想…

python数据实时传给unity工程并绘制出来

python # 服务器端代码 import socket import random import struct import time# 创建一个服务器Socket server_socket socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 监听的地址和端口 host 127.0.0.1 port 12345# 绑定地址和端口 server_socket.bind((host, port…

UE4_官方动画内容示例1.2_动画蓝图——使用蓝图告知Actor播放动画

展示了两个示例&#xff1a;在其中一个示例中&#xff0c;使用蓝图告知Actor播放动画&#xff0c;在另外一个示例中&#xff0c;展示了告知Actor播放动画的动画蓝图&#xff08;例如&#xff0c;此示例展示了如何将变量从蓝图传递给动画蓝图&#xff0c;并演示了如何将现有姿势…