旅行路线可视化研究与实现(Java+Android+Eclipse实现的旅游APP)

news2024/12/24 9:39:53

目 录
1 概论 1
1.1 研究现状 1
1.2 系统开发意义 1
1.3 系统开发背景 2
2 开发环境以及相关技术 5
2.1 Eclipse 5
2.2 Adroid 5
2.2.1 基本概念 5
2.2.2 简介 6
2.2.3 系统架构 6
2.2.4 四大组件 7
2.3 Java语言 7
2.4 SQLite 7
2.4.1 简介 7
2.4.2 架构 7
2.4.3 特点 8
2.5 FastJson 8
2.5.1 简介 8
2.5.2 FastJson解析JSON步骤 9
3 需求分析 13
3.1 可行性分析 13
3.1.1 技术可行性 13
3.1.2 经济可行性 13
3.1.3 社会可行性 13
3.2 功能需求分析 14
3.3 特性需求分析 14
4 概要设计 16
4.1 系统总体功能结构 16
4.2 系统总体架构 17
5 详细设计与实现 18
5.1 系统总体功能设计 18
5.1.1 服务器端说明 18
5.1.2 客户端说明 18
5.2 系统的实现 19
5.2.1 活动模块 19
5.2.2 游记模块 20
5.2.3 导航模块 23
5.2.4 我的模块 25
5.3 实现的技术点 26
5.3.1 界面布局的实现 26
5.3.2 代码中所用到的技术 31
6 软件测试 37
6.1 软件测试的重要性 37
6.2 测试实例的研究与选择 37
6.3 系统运行情况 38
6.4 系统评价 41
7 总结 43
参考文献 44
致 谢 45
外文原文 46
中文翻译 57
3 需求分析
系统分析的真正含义就是对系统,从技术可行性、经济可行性以及操作可行性来进行分析。
3.1 可行性分析
在这里就依次从技术的、经济的、社会的可行性三个方面来对本旅游导航APP进行深入的分析和研究。
3.1.1 技术可行性
该软件是基于Java语言、并以SQLite为后台数据库。硬件、软件的性能要求、环境条件等各项条件均良好。利用现有技术条件预计完全可以达到该软件的功能目标。时间安排相对比较充裕,预计完成没有问题。
由以上分析可以知道:本设计是具有技术可行性的。
3.1.2 经济可行性
本设计采用的开发软件都是开源的,不需用额外花费费用,这样削减很多的精力和资源,起到减少成本的作用,因此在经济上具有可行性。
由以上分析可以知道:本设计具有经济的可行性。
3.1.3 社会可行性
本设计的社会可行性主要需要从法律因素、用户使用可行性这两方面进行研究。
1.法律因素
本设计是根据80、90的青年人旅行的实际情况开发研制的,是通过大量的调研得出的,系统的软件设计是在独立的环境下完成的,无可供抄袭的软件产品。
2.用户使用可行性
本设计对用户的要求,除了需要具备移动设备以及第三方账号外,并不需要特别的技术能力。使用系统的管理员,需要具备对java语言及Android开发环境的使用能力,在投入使用前,无需对操作系统的人员进行培训。这样减少了投入成本简化了操作环节。
由以上分析可以知道:本设计完全具有社会的可行性。
3.2 功能需求分析
Android系统目前在市场上占有很大的份额,从2010前Android就已经呈现出很强劲的发展势头,而且到目前为止,还处于不断的上升阶段。无论你走在大街上、校园里、地铁上亦或是公交上,总能看到人们拿着智能手机专心致志的做自己的事情,而且不难发现,绝大多数都是Android手机,人们低头聚精会神的玩游戏、看小说、刷刷微博等等。手机中安装的各种App可以丰富并且满足人们对业余生活的要求以及期望,其中的游戏娱乐、在线购物也是极大的刺激着整个社会的消费水平。随着时代的不断发展,兼娱乐与通信功能的手机越发的流行,成为人们的一种新的追求。因而,这就更进一步的促进激发着手机软件App研发人员的热情与积极性。
综上,本设计是为了实现一个方便用户出行,并可以推荐旅游景点的目标。用户可以通过浏览驴友们在野外徒步旅行是的场景,全方位的了解自己想要去的景点。通过展示的信息,用户可以方便的了解一个景点的人文特色,最近是否有活动,是否拥有优惠价,以及根据时间分类,可以准确的推荐最近一段时间的旅游团动向,并附有旅游团的联系方式,方便用户直接用电话进行咨询,从而来确定是否参加本次活动;并且在此基础上,根据数据源的数据结构以及字段分析,把旅游的信息按地点进行一些分类,每个城市的旅游信息就可以直观的展现在用户的面前,并且将旅游的类型进行了汇总,冒险类、休闲类、娱乐类等丰富的信息以供用户选择,此外也考虑到了用户的经济承受能力,还实现了根据本次旅游的价格信息进行进一步的整合,可以让用户更加直观并且很快的找见适合自己经济承受能力的旅游景点。当然,光有这些信息是远远不够的,用户之间最好能够进行互动,互相交流旅游心得,欣赏了解对方去过的地方,还可以进行点赞,要想实现这个功能,当然是离不开第三方登陆的,微博、QQ可以任意选择,因而就要求用户必须要拥有一个属于自己的第三方的账号,在登陆成功后可以对个人信息进行查看。
3.3 特性需求分析
一个较好的软件应该具有以下特性:
1、易操作和功能简单明确。一个好的旅游导航系统应该功能明确,用户可以很快的熟悉使用流程,而不是看到界面不知道应该如何的操作,即操作要简单,界面友好易懂。
2、软件功能流畅。软件运行时候不会发生崩溃和卡顿等问题,整个界面操作起来快捷流畅。
3、软件易维护性。系统各个设计模块明确,核心代码要有必要的注释,方便软件的后期维护。

/*
 * Copyright (c) 2013. wyouflf (wyouflf@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lidroid.xutils;

import android.app.Activity;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.view.View;
import com.lidroid.xutils.util.LogUtils;
import com.lidroid.xutils.view.EventListenerManager;
import com.lidroid.xutils.view.ResLoader;
import com.lidroid.xutils.view.ViewFinder;
import com.lidroid.xutils.view.ViewInjectInfo;
import com.lidroid.xutils.view.annotation.ContentView;
import com.lidroid.xutils.view.annotation.PreferenceInject;
import com.lidroid.xutils.view.annotation.ResInject;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.EventBase;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ViewUtils {

    private ViewUtils() {
    }

    public static void inject(View view) {
        injectObject(view, new ViewFinder(view));
    }

    public static void inject(Activity activity) {
        injectObject(activity, new ViewFinder(activity));
    }

    public static void inject(PreferenceActivity preferenceActivity) {
        injectObject(preferenceActivity, new ViewFinder(preferenceActivity));
    }

    public static void inject(Object handler, View view) {
        injectObject(handler, new ViewFinder(view));
    }

    public static void inject(Object handler, Activity activity) {
        injectObject(handler, new ViewFinder(activity));
    }

    public static void inject(Object handler, PreferenceGroup preferenceGroup) {
        injectObject(handler, new ViewFinder(preferenceGroup));
    }

    public static void inject(Object handler, PreferenceActivity preferenceActivity) {
        injectObject(handler, new ViewFinder(preferenceActivity));
    }

    
    private static void injectObject(Object handler, ViewFinder finder) {

        Class<?> handlerType = handler.getClass();

        // inject ContentView
        ContentView contentView = handlerType.getAnnotation(ContentView.class);
        if (contentView != null) {
            try {
                Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
                setContentViewMethod.invoke(handler, contentView.value());
            } catch (Throwable e) {
                LogUtils.e(e.getMessage(), e);
            }
        }

        // inject view
        Field[] fields = handlerType.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                ViewInject viewInject = field.getAnnotation(ViewInject.class);
                if (viewInject != null) {
                    try {
                        View view = finder.findViewById(viewInject.value(), viewInject.parentId());
                        if (view != null) {
                            field.setAccessible(true);
                            field.set(handler, view);
                        }
                    } catch (Throwable e) {
                        LogUtils.e(e.getMessage(), e);
                    }
                } else {
                    ResInject resInject = field.getAnnotation(ResInject.class);
                    if (resInject != null) {
                        try {
                            Object res = ResLoader.loadRes(
                                    resInject.type(), finder.getContext(), resInject.id());
                            if (res != null) {
                                field.setAccessible(true);
                                field.set(handler, res);
                            }
                        } catch (Throwable e) {
                            LogUtils.e(e.getMessage(), e);
                        }
                    } else {
                        PreferenceInject preferenceInject = field.getAnnotation(PreferenceInject.class);
                        if (preferenceInject != null) {
                            try {
                                Preference preference = finder.findPreference(preferenceInject.value());
                                if (preference != null) {
                                    field.setAccessible(true);
                                    field.set(handler, preference);
                                }
                            } catch (Throwable e) {
                                LogUtils.e(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }

        // inject event
        Method[] methods = handlerType.getDeclaredMethods();
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                Annotation[] annotations = method.getDeclaredAnnotations();
                if (annotations != null && annotations.length > 0) {
                    for (Annotation annotation : annotations) {
                        Class<?> annType = annotation.annotationType();
                        if (annType.getAnnotation(EventBase.class) != null) {
                            method.setAccessible(true);
                            try {
                                // ProGuard:-keep class * extends java.lang.annotation.Annotation { *; }
                                Method valueMethod = annType.getDeclaredMethod("value");
                                Method parentIdMethod = null;
                                try {
                                    parentIdMethod = annType.getDeclaredMethod("parentId");
                                } catch (Throwable e) {
                                }
                                Object values = valueMethod.invoke(annotation);
                                Object parentIds = parentIdMethod == null ? null : parentIdMethod.invoke(annotation);
                                int parentIdsLen = parentIds == null ? 0 : Array.getLength(parentIds);
                                int len = Array.getLength(values);
                                for (int i = 0; i < len; i++) {
                                    ViewInjectInfo info = new ViewInjectInfo();
                                    info.value = Array.get(values, i);
                                    info.parentId = parentIdsLen > i ? (Integer) Array.get(parentIds, i) : 0;
                                    EventListenerManager.addEventMethod(finder, info, annotation, handler, method);
                                }
                            } catch (Throwable e) {
                                LogUtils.e(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }
    }

}

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

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

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

相关文章

《Redis 深度历险:核心原理与应用实践》学习

1、Redis的5种基础数据结构 Redis的5种基础数据结构&#xff1a;string (字符串&#xff09;、list (列表 &#xff09;、hash (字典&#xff09;、 set (集合&#xff09;、zset (有序集合&#xff09;。 Redis所有的数据结构都以唯一的key字符串作为名称&#xff0c; 然后通…

基于粒子群优化算法的边缘链接用于边缘检测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

艾美捷FLIVO探针:用于细胞活体凋亡检测,助力科研!

细胞凋亡在胚胎发育、造血、免疫系统的成熟以及维护正常组织和器官的细胞恒定与生长平衡&#xff0c;乃至机体衰老方面都起着重要作用。因此&#xff0c;有关凋亡的研究在临床和基础等各个领域已经广泛开展,凋亡细胞的检测方法显得非常重要。 FLIVO(荧光活体)是一种强大的无创检…

首个搭载8MP摄像头的单SoC行泊一体方案来袭,已拿下多家车企定点

行泊一体正在进入前装规模化上车的关键周期&#xff0c;但同时产品的升级战争也在全面爆发。 《高工智能汽车》了解到&#xff0c;国内领先的智能驾驶技术供应商——AutoBrain重磅推出了国内首个搭载800万像素摄像头的单SoC行泊一体方案。据悉&#xff0c;这是全球量产首发搭载…

dubbo消费者访问不到docker里面的生产者

版本 dubbo3.0.7 Docker version 20.10.21, build baeda1f docker zookeeper lastest 背景 一个dubbo的项目&#xff0c;生产者和消费者之间使用zookeeper管理。 现将消者和zookeeper部署到了docker中&#xff0c;二者使用的都是桥接网络。 消费者仍然在idea中编写逻辑。 服…

正片工艺、负片工艺,这两种PCB生产工艺的差异到底是什么?

在前文《什么是加成法、减成法与半加成法&#xff1f;》中&#xff0c;我们提到&#xff1a;减成法仍为当前PCB生产工艺的主流&#xff0c;那么&#xff0c;其中的两大代表工艺——正片工艺、负片工艺&#xff0c;又是怎样的呢&#xff1f; 请看下图&#xff1a; 当然&#xf…

一起用Go做一个小游戏(下)

打包资源使用file2byteslice包我们可以将图片和config.json文件打包进二进制程序中&#xff0c;之后编译生成一个二进制程序。然后拷贝这一个文件即可&#xff0c;不用再拷贝图片和其他配置文件了。golang有很多第三方包可以将打包资源&#xff0c;原理其实很简单——读取资源文…

面试官:使用 RocketMQ 怎么进行灰度发布?

今天来聊一聊 RocketMQ 的灰度方案。 灰度发布是指在黑与白之间&#xff0c;平滑过渡的一种发布方式。在大流量的系统中&#xff0c;如果一次升级改造范围比较大&#xff0c;或者影响内容不太确定&#xff0c;一般会采用切量的方式进行升级&#xff0c;这样可以减少生产变更带…

面试官:MySQL 中 varchar(n) 中 n 最大取值为多少?

前置知识 要回答这个问题&#xff0c;首先我们得先知道 MySQL 存储一条记录的格式长什么样子。 以 Compact 行格式作为例子&#xff0c;它长这样&#xff1a; 可以看到&#xff0c;一条完整的记录分为「记录的额外信息」和「记录的真实数据」两个部分。 这里重点讲讲记录的…

探究L298N模块烧毁的原因

目录 基础介绍 代码思路 基础介绍 L298N电机驱动版主要由两个核心组件构成&#xff1a; L298N 驱动芯片78M05 稳压器型号&#xff1a; L298N封装&#xff1a; Multiwatt15V 描述&#xff1a;电源电压&#xff1a;4.5V~46V 特性&#xff1a;过流保护(OCP)&#xff1b;过热保…

在线教程 | 用「网红项目」DeepSOCIAL 进行社交距离监测

By 超神经 内容一览&#xff1a;YOLO v4 是一个实时的、高精度的目标检测模型&#xff0c;本教程将详细讲解如何基于 YOLO v4 和 SORT 算法&#xff0c;实现在多目标条件下的人群距离检测。 关键词&#xff1a;YOLO v4 SORT 多目标检测 新冠疫情爆发初期&#xff0c;「保持…

VSCODE安装ChatGPT插件

zh1&#xff1a;首先在插件商店搜索ChatGPT中文版 然后点击安装就可以 2&#xff1a;chatGPT插件目前需要登陆账号才能使用&#xff0c;官方介绍下一个版本会有升级(不需要登陆) a:前往 ChatGPT 并登录或注册。 首先要先注册&#xff0c;注册的时候邮箱号可以填国内的也可以用…

利他合作,共赢未来 | 数商云全国渠道代理商招募政策发布

12月2日下午&#xff0c;以“利他合作&#xff0c;共赢未来”为主题的数商云全国渠道代理商招募政策发布会在广州顺利召开&#xff0c;与线上线下来自全国各地区的60家优质厂商共同解读数商云首次公开的招商政策、深入体验数商云全线产品体系&#xff0c;挖掘千亿数字化采购市场…

leecode#有效的电话号码#第十行#上升的温度

题目描述&#xff1a; 给定一个包含电话号码列表&#xff08;一行一个电话号码&#xff09;的文本文件 file.txt&#xff0c;写一个单行 bash 脚本输出所有有效的电话号码。 你可以假设一个有效的电话号码必须满足以下两种格式&#xff1a; (xxx) xxx-xxxx 或 xxx-xxx-xxxx。…

20个有用的Excel数据分析函数(教程含案例)

Microsoft Excel 是一种简单而强大的数据分析工具。Excel 是当今行业中广泛使用的软件应用程序,用于生成报告和业务洞察。Excel 包含超过 450 个函数,并且每年都会添加更多函数。在这里,我们介绍了那些主要用于数据分析的功能。 MAX/MIN MAX和MIN函数顾名思义。MAX将找到范…

零基础CSS入门教程(8)——CSS设置字体

本章目录1.任务目标2.css设置字体3.代码演示4.小结1.任务目标 我们前几个小结学习了&#xff0c;css的选择器&#xff0c;和及基本的改变字体颜色。我们这一小结学习一下设置字体的一些功能 2.css设置字体 (1)font-size这个是设置字体大小&#xff0c;浏览器一般默认字体是1…

剪映专业版常用快捷键(Pr 习惯)

剪映专业版提供了两组常用快捷键&#xff0c;一组适应 Final Cut Pro X 用户的习惯&#xff0c;另一组则是为了适应 Adobe Premiere Pro 用户的习惯。本文列出了剪映专业版&#xff08;v3.6&#xff09;的常用快捷键&#xff0c;以让 Pr 用户快速上手剪映。时间线相关快捷键分割…

无接触体征监测的技术和应用

近年来&#xff0c;由于传感器和微电子技术的飞速发展&#xff0c;基于智能传感器的无接触体征监测技术成为研究热点。尤其是近年来传感器技术和人工智能算法的不断创新&#xff0c;使人们在对人体生理、生化参数等进行监测时能够达到实时、精确和智能化的目的。 智能传感器主要…

软件设计师教程(三)计算机系统知识-计算机体系结构

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 安全性、可靠性与系统性能评测基础知识软件设计师教程计算机安全概述计算机的安全等级安全威胁影响数据…

Linux进程的创建

fork是一个系统调用&#xff0c;系统调用的流程&#xff0c;流程的最后会在sys_call_table中找到相应的系统调用sys_fork。&#xff0c;sys_fork的定义如下&#xff1a; SYSCALL_DEFINE0(fork) { ......return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0); }sys_fork会调用_do_fo…