英语作为全球应用最广泛的语种,广泛的应用与社会中的各个方面。近年来,随着移动互联网的崛起和智能移动设备的普及,让更多的人们热衷于开发英语单词学习类的应用软件。而Android系统以其优秀的UI设计,良好的用户体验以及成熟的开发技术,成为开发的最佳选择。本文首先介绍了项目背景及国内发展状况,然后阐述了在Android平台下对该软件的设计和实现过程,能够让人们可以在移动设备上享受玩转英语的快乐。本软件主要实现了软件对英语的翻译,查询,单词本,每日一句等功能。本软件主要是使用Android自带的轻量级数据库SQLite来保存单词信息,系统通过SQLite数据库的query方法来查找到与指定英文相对应的单词的中文释义。当然,对于查询到的生疏的单词可以添加到单词本以便于随时复习。在此基础上,我们设计出基于Android平台设计和开发自主学习应用软件。要功能有:每日一句、查词、翻译、生词本。在一定程度上给同学们便利了生活。
关键词:Android;电子词典;英文单词;移动互联网
1绪论
1.1项目背景
如今,英语在人们的工作,学习中显得越来越重要了,而手机词典软件的出现无疑带来了极大的便利,遇到生疏的英语单词,现在只要拿起手机就能轻松解决。以前人们用最简单的辞典,在众多的资料中翻阅、查找,费时、费力,而且应用性非常差。设计这么一个玩转英语系统,使得用户可以便捷,快速的进行操作,同时也达到了稳定,准确的目的。基于Android的玩转英语程序的设计可以进一步扩大学习英语的途径,让广大公众能够随时随地方便且快捷地认识与记忆英语查词,以提高自身的英语水平。本软件提供从初次记忆查词到熟记查词的所有功能,帮助大家科学学习。当您初次使用本软件记忆查词后,系统会自动为您制定学习复习计划,帮助您科学快速地完成记忆查词的过程。软件提供测试功能,帮助您自我检测学习状态。更好地发挥了Android技术对移动互联网的现实性作用。
2.1Android操作系统
Android是一种以Linux为基础的开放源代码操作系统,主要用于便携设备。Android是一个完整、开放、免费的手机平台,其具有以下突出特点:
1)开放性:在优势方面,Android平台首先就是其开放性,开放的平台允许任何移动终端厂商加入到Android联盟中来。显著的开放性可以使其拥有更多的开发者,随着用户和应用的日益丰富,一个崭新的平台也将很快走向成熟。
2)应用程序无界限:Android上的应用程序可以通过标准的API访问核心移动设备。通过互联网,应用程序可以他们的功能可供其他应用程序使用。
3)应用程序可以轻松嵌入地嵌入网络:应用程序可以轻松的嵌入HTML、JavaScript和样式表,还可以通过WebView显示网络内容。
4)无缝结合的Google应用:Android平台的手机可以很好的结合google服务。如google地图、邮件、搜索等。
2.1.1Android系统框架
Android操作系统架构和其他操作系统一样,采用了分层的架构。从架构图看Android系统架构为四层结构,从上层到下层分别是应用程序层、应用程序框架层、系统运行库层以及Linux内核层。如图2-1所示:
图2-1Android系统框架图
(1)应用程序层
该层提供一些核心应用程序包,例如电子邮件、短信、日历、地图、浏览器和联系人管理等。同时,开发者可以利用Java语言设计和编写属于自己的应用程序,而这些程序与那些核心应用程序彼此平等、友好共处。
(2)应用程序框架层
(3)系统库和Android运行时
系统库包括九个子系统,分别是图层管理、媒体库、SQLite、OpenGLEState、FreeType、WebKit、SGL、SSL和libc。Android运行时包括核心库和Dalvik虚拟机,前者既兼容了大多数Java语言所需要调用的功能函数,又包括了Android的核心库,比如android.os、android.net、android.media等等。后者是一种基于寄存器的java虚拟机,Dalvik虚拟机主要是完成对生命周期的管理、堆栈的管理、线程的管理、安全和异常的管理以及垃圾回收等重要功能。
(4)Linux内核
Android核心系统服务依赖于Linux2.6内核,如安全性、内存管理、进程管理、网络协议栈和驱动模型。Linux内核也是作为硬件与软件栈的抽象层。驱动:显示驱动、摄像头驱动、键盘驱动、WiFi驱动、Audio驱动、flash内存驱动、Binder(IPC)驱动、电源管理等。
2.1.2Android应用程序
Android应用层主要有四个部分组成,分别是:活动(Activity),用于显示功能;服务(Service),相当于后台运行的Activity;广播(BroadcastReceiver),用于接收广播;内容提供者(Intent),用于存储并检索数据。
(1)Activity
一个Activity通常展现为一个可视化的用户界面,是Android程序与用户交互的窗口,也是Android组件中最基本也是最复杂的一个组件。从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个界面状态,需要做很多持久化的事情,还需要妥善管理生命周期,和一些转跳逻辑。对于开发者而言,需要派生一个Activity的子类,进而进行编码实现各种功能方法。
(2)service
(3)BroadcastReceiver
广播接收者,不执行任何任务,广播是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件。BroadcastReceiver不包含任何用户界面。然而它们可以启动一个Activity以响应接受到的信息,或者通过NotificationManager通知用户。可以通过多种方式使用户知道有新的通知产生:闪动背景灯、震动设备、发出声音等等。通常程序会在状态栏上放置一个持久的图标,用户可以打开这个图标并读取通知信息。在Android中还有一个很重要的概念就是Intent,如果说Intent是一个对动作和行为的抽象描述,负责组件之间程序之间进行消息传递。那么BroadcastReceiver组件就提供了一种把Intent作为一个消息广播出去,由所有对其感兴趣的程序对其作出反应的机制。
(4)ContentProvider
作为应用程序之间唯一的共享数据的途径,ContentProvider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。Android有一个独特之处就是,在Android中,每个应用程序都是用自己的用户ID并在自己的进程中运行。这样的好处是,可以有效地保护系统及应用程序,避免被其他不正常应用程序所影响,每个进程都拥有独立的进程地址空间和虚拟空间。Android的数据(包括files,database等…)都是属于应用程序自身,其他的应用是不能访问到的,更无法直接进行操作。所以如果你想实现不同应用之间的数据共享,就不得不用contentprovider了。为了使其他程序能够操作数据,在Android中,可以通过做成ContentProvider提供数据操作的接口。其实对应用而言,也可以将底层数据封装成ContentProvider,这样可以有效的屏蔽底层操作的细节,并且使程序保持良好的扩展性和开放性。
2.2SQLite数据库
SQLite,是一款轻型的数据库,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。
2.3调用有道翻译API
有道翻译API,为广大开发者提供开放接口。您的应用或网站可通过有道翻译API,构建丰富多样的功能或应用,为用户带来即时,准确,方便的查词或翻译体验,从而降低语言理解与应用门槛。依靠有道翻译网络数据挖掘和统计机器翻译技术实力做基础,加上您的智慧,将创造出更优良的体验和创新的功能。
json数据格式举例
{
"errorCode":0
"query":"good",
"translation":["好"],//有道翻译
"basic":{//有道词典-基本词典
"phonetic":"gd"
"uk-phonetic":"gd"//英式发音
"us-phonetic":"ɡd"//美式发音
"explains":[
"好处",
"好的"
"好"
]
},
"web":[//有道词典-网络释义
"key":"good",
"value":["良好","善","美好"]
{...}
}
在项目查词模块翻译模块通过访问网络接口,解析返回结果显示数据,重点部分代码为:publicstaticWorddoTranslateCc(Stringquery){
Wordword=null;
//以下URL为申请的有道API的key
try{
StringjsonData="";
//向指定的URL发送Http请求
//取得服务器返回的响应
HttpEntityentity=response.getEntity();
BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(entity.getContent()));
Stringline="";
while((line=bufferedReader.readLine())!=null){
jsonData=jsonData+line;
word=newWord();
//详细请百度一下有道API
JSONObjectjsonObject=newJSONObject(jsonData);
word.setQuery(query);
word.setTranslation(jsonObject.getJSONArray("translation").getString(0));
JSONObjectbasic=jsonObject.getJSONObject("basic");
//音标
word.setUk(basic.getString("uk-phonetic").trim());
word.setUs(basic.getString("us-phonetic").trim());
//返回json数组
StringotherString="";
JSONArrayotherArray=basic.getJSONArray("explains");
for(inti=0;i otherString+=";"+otherArray.getString(i); word.setExplains(otherString.substring(1)); }catch(Exceptione){ returnword; 3项目总体设计与需求分析 3.1需求分析 本部分从功能性需求与非功能性需求对项目进行需求分析: 3.1.1功能性需求分析 在软件设计之前,我们要做的工作就是对电子词典的流程,操作等,做出详细的调查,从而更加了解项目所需实现的功能。根据用户查单词和记忆单词的要求和记录所查生词的习惯,玩转英语软件实现后所达到的功能有: (1)每日一句 将100个精美句子和翻译导入SQLite数据库,然后每次打开程序随机显示一句,让用户可以随时随地学好英语。 (2)查词 实现单词或词组的查词功能,提供中英文释义。 (3)翻译 实现中英文句子互译,方便用户学习。 (4)生词本 实现用户保存生词到生词本的功能,添加重点生词方便用户复习。当再次点击生词本中的单词时,再次跳回到查询该单词的界面,方便二次查询。 3.1.2非功能性需求分析 软件产品的非功能需求常被人们忽视。所谓非功能性需求,是指软件产品为满足用户业务需求而必须具有且除功能需求以外的特性。事实上,软件铲平的非功能性需求不仅决定产品的质量,还在很大程度上影响产品的功能需求。本项目涉及的非功能需求有: (1)低资源消耗 (2)易用性 易用性是与一组规定或者潜在的用户为使用其软件所需做的努力和对这样的使用所作的评价有关的一组属性。具体包括: 易理解性:与用户为人质逻辑概念即其应用范围所花的努力有关的软件属性。 易学习性:与用户为学习软件应用所花的努力有关的软件属性。 易操作性:与用户为操作和运行控制所花的努力有关的软件属性。如带首字母筛选功能的下拉列表等。 3.1.3用户UI设计 3.2系统模块划分与操作流程图 3.2.1模块划分 根据功能性需求,系统模块划分为:每日一句模块、查词模块、翻译模块、生词本模块。对应的模块图如图3-2-1: 图3-2-1系统模块图 各模块主要功能详细介绍如下: 先将100个精美语句与翻译从Excle表导入SQLite数据库,在程序开始执行的第一个页面显示该语句,可方便用户随时随地学习英语。 1)输入所查单词或词组 用户在所给的EditText文本框中输入所要查询的单词或词组。 2)查询结果显示 当用户输入所要查询的单词或词组后,单击翻译按钮会显示查询结果,如果输入单词时英文会显示对应的汉语意思以及英式和美式发音,如果输入的是汉语词语会显示对应的英文单词。 3)添加到生词本 完成所查的单词和词组后,单击保存到生词本按钮用户可将所查单词和词组存入生词本,方便记忆和学习。 该模块提供中英文互译,在文本框输入所要查询的中文或英文句子,点击翻译按钮,程序通过调用有道翻译API对所输句子进行翻译,然后将返回结果用JSON解析显示出来。 1)删除 单击生词本的删除按钮,可将生词本中存入的单词会词组删除掉。 2)再次查询 单击生词本中的某个单词可再次跳到查询该单词的界面,方便用户再次查询该单词或词组。 3.2.2系统操作流程图 该软件的操作流程图如图3-2-2所示: 图3-2-2系统操作流程图 3.4数据库设计 本系统采用的是sqlite数据库,sqlite数据库是Android自带的小型数据库,可以将少量的数据存放在该数据库中。针对不同的用户的生词是不同的,可以很方便的将生词导入到数据库中,也可以很方便的将单词从数据库中删除。此软件中的数据表的关系也比较简单,只有一张表用来存放添加到单词本中的单词具体设计如下表所示: 数据库名称 sqlite.db 表名 dict 字段名 _id,title,body 说明:title:存放英文单词。body:存放相应的英文单词的中文解释。数据库定义为sqlite.db的原因是:android平台下采用的数据库是sqlite3,运行后生成数据库的名称.db文件.定义好的数据库可以直接导入到/data/data/com.briup.dictionary/databases/sqlite.db。这样生词本的数据就可以直接在模拟器中显示出来。 在线时的服务器端用的Oracle数据库用来存储单词的基本信息(单词的名称和单词的中文释义),客户端用的是android自带的sqlite数据库。这里将首先介绍如何进行Android数据库连接,Android中自带SQLite数据库,这是一个十分小型的数据库,这样正适合Android这种移动平台使用。Android数据库存储的位置在data/data/<项目文件夹>/databases/目录下,Android是利用ContentProvider作为内容提供商,SQLiteOpenHelper数据库帮助类来进行对数据库的创建和操作。通过Context.getContentResolver()方法直接对数据库进行操作。程序中数据库类为DBHelperextendsSQLiteOpenHelper(继承关系),内容提供类DBProviderextendsContentProvide(继承关系)。其次介绍服务器端的数据库的详细设计,再介绍服务器端和客户端的数据库的连接。 3.4.1数据库的创建 Android提供了标准的数据库创建方式。继承SQLiteOpenHelper,实现onCreate()和onUpgrade()两个方法,有个好处就是便于数据库版本的升级,连接数据库的算法见程序清单。数据库如果创建不成功则抛出FIleNotFoundException异常。服务器端数据库的创建主要是通过DOS利用命令进行创建的,详细的创建命令在2.1.1中已经详细的做了介绍,此处不再进行赘述。 3.4.2.数据库的操作 3.4.3数据的查看 Android中程序是利用Cursor游标类指向数据表中的某一项,然后进行查询数据,用Log日志显示出来。查询时用的方法是数据库本身的查询方法query(),需要注意的是这个方法比较复杂,他有8个参数,因为它将一个完整的SQL语句拆成了若干个部分: 第一个参数table:表名,相当于SQL的from后面的部分。在此还要注意如果和多表联合查询时,就用逗号将两个表名分开,拼成一个字符串的table值。 第二个参数是columns,要查询出来的列名。相当于SQL的select后面的部分。 第三个参数是selection,查询的条件,相当于SQL的where后面的部分,在这个语句中允许使用“?”,也就是说这个用法和JDBC中的PreparedStatement的用法相似。 第四个参数selectionArgs,对应于selection的值,selection有几个问号,这里就得用几值。 第五个参数groupBy,相当于SQL的groupby后面的部分。 第六个参数having,相当于SQL的having后面的部分。 第七个参数orderBy,相当于SQL的orderby后面的部分,如果是倒序,或者是联合排序,可以写成类似这样:StringorderBy=“iddesc,name”。 第八个参数limit,指定的结果集的大小,它和Mysql的limit用法不太一样,Mysql可以指定从多少行开始之后取多少条,例如,“limit100,10”,但是这里只支持一个数值。 注意:游标查询时,必须把Cursor移动到第一个位置,即moveToFirst(),因为每次查询时,游标都会从第一个往后查找,通常在查询数据库之前进行。此外,游标和数据库一样都要及时关闭,要不会出现异常。其详细代码见程序清单。在Oracle中查询用到的也是数据的query()方法,他用到的参数只有一个就是sql语句,sql语句的写法是sql=“selectsum(字段名)as别名from数据表where条件表达式,”例如Stringsql="select*fromb_dictwherename="。最后要执行sql语句,用法如下setrs=conn.excute(sql),用rs(别名)表示获取统计的值。 4系统的详细设计 4.1系统主界面的设计一般思路 一般我们制作头部菜单栏是为了提升软件的可操作性,可以用的是TabHost+RadioGroup相结合的方法来制作这个部分的。菜单栏的底部位置是通过TabHost这个布局来实现的,然后是LinearLayout的线性布局来布置内容。内部的选项卡是通过TabWiget来实现。 首先建立好Android工程(我的工程名为:ScheduleManager),在工程下的res/layout下建立一个名为main的空xml文件,然后在这个文件里按照思路来添加布局代码。 主界面的菜单选项使用RadioGroup来建立,在这里的布局中RadioGroup里容纳4个RadioButton,而RadioButton是单选按钮。在这种情况下就只有也只能有一个RadioButton能被选择,并且在开始时默认了第一个按钮被选中。其中RadioButton的实现方式是在设置了内部的文字,然后再按钮的顶部上添加上图片,实现的代码如下: android:text="@string/main_date" android:drawableTop="@drawable/tab_date" android:id="@+id/radio_button0" android:checked="true" style="@style/main_tab_bottom"/> 从上述代码可以看到,在菜单的每个选项卡样式都是调用了style上的main_tab_bottom来实现样式的,而main_tab_bottom的背景background的值是@drawable/btn_bg,btn_bg不是一个简单的背景图片,而是一个xml文件,通过这个文件可以实现菜单选项卡切换时的背景切换的效果,使得这个菜单栏更加的美观,代码是使用了安卓的selector来实现,在这里是通过不停的条件来判断使用哪一个item的,里面包括了几个属性值,如是否获得焦点、是否响应事件、是否点击三个条件。实施的代码如下: 制定完主页面布局后,在src/com.manage.activity下的MainPage文件中OnCreate(OnCreate方法是用来初始化Activity实例对象的)中调用布局,到现在为止顶部菜单栏的布局已经基本完成,但现在里面所对应的内容还是空的。所以就需要在这里给tabHost中添加tab内容,以第一格的tab为例,先是通过Intent的方式新建个mDate,用来实现页面的跳转的方法,然后动态用tabHost来通过addTab的方法添加对应TabSpec的值和各个属性。 最后在添加RadioGroup的选择操作函数,这里是通过switch来完成对应按钮的功能的实现,在每个case项中通过tabHost.setCurrentTabByTag来给与特定的值实现页面上的跳转。 在上述思路下我们的详细的效果图如下: 图4-1系统主界面 4.2系统触摸反应及页面跳转的一般设计思路 系统主界面默认选择界面在头部菜单栏下方。 (1)首先是建立一个布局文件,上面一部分是显示部分。使用的是一个TextView类,对应的在的CalendarActivity文件中加入函数来添加头部的年份等信息。 首先需要写了一个CalendarView类,这是为显示所写的一个类,在其中使用重载的方法定义了几个不同参数的CalendarView,用于不同的情况。在CalendarActivity中实例化CalendarView并且使用CalendarView中的一个方法。 CalendarView(this,getResources(),jumpMonth,jumpYear,year_c,month_c,day_c);然后书写方法来添加头部信息。 首先是对这个页面的头部进行布局,通过动态化的方法来完成。 然后建立一个可以进行改变值的StringBuffer类型的参数textDate。对这个参数进行append操作里。其中有一个判断的条件函数,是通过calV.getLeapMonth()的值惊醒判断的。完成后对界面使用setText方法来赋值到界面上。 最后是对界面的一些美化,同样使用动态布局模式进行。 (2)下面是界面中主体期部分显示的完成 在CalendarActivity文件初始化实例对象时加入动态添加布局文件的方法。我将此方法命名为addGridView。在这个方法中同样是先进行动态化布局,由于这里用的是GridView,这个GridView应用于将一系列的空间组织成二维网格的形式显示出来,所以适用于我在这里进行的日期界面的建立。 同样的首先是动态化布局的建立,这可以实例化GridView为gridView参数进行的。在这里需要添加GridView控件的列为7,列宽为46。并且还加上判断屏幕大小的条件,这需要加入取得屏幕大小的对应函数,这里如果是800*480屏幕的话,就将列宽设置为69。然后进行设置水平和竖直的间距、取值边框、设置居中等操作。 在这个方法里面还需加入个OnTouch方法,用来将gridView中的触摸事件回传给gestureDetector,进行下面的触摸操作,即: //将gridview中的触摸事件回传给gestureDetector @Override publicbooleanonTouch(Viewv,MotionEventevent){ returnCalendarActivity.this.gestureDetector.onTouchEvent(event); }); 创建完的布局后,是在里面添加上具体的信息。就当前显示的页面来说,是建立几个对应的参数,用来显示或传接数据。例如在函数开始时就String[]dayNumber=newString[49];这是作为对GridView控件内进行标记序列的,用于下面条件语句的判断等,还有就是界面内的一些控件名的实例化。然后是动态化的对页面进行属性值的设置。 下一步是当前信息的显示,这也需要条件函数来判断是否为符合条件的数据,也是来判断参数position是否在范围内。 通过上述的步骤基本完成了界面中的初步建设。 4.3系统的进入与单词查询模块模块 图4-2-1英文查词及保存生词 图4-2-2中文查词 4.4单词的翻译模块 对于一款良好的自主学习应用软件而言,可以对自己不熟悉的短句句子进行翻译,具体效果如下: 图4-3句子翻译模块 4.5生词本模块 在生词本模块中有在查词过程中保存的生词,在该模块中我们可以对生词进行管理,可以删除生词以及当点击某个生词时可以再次跳转到查询该词的界面,方便二次查询。具体截图如下。 图4-4生词本模块 5系统的测试 5.1程序调试 在设计系统的过程中,存在一些错误是必然的。对于语句的语法错误,在程序运行时自动提示,并请求立即纠正,因此,这类错误比较容易发现和纠正。但另一类错误是在程序执行时由于不正确的操作或对某些数据的计算公式的逻辑错误导致的错误结果。这类错误隐蔽性强,有时会出现,有时又不出现,因此,对这一类动态发生的错误的排查是耗时费力的。 5.2程序的测试 5.2.1测试的重要性及目的 (1)测试的重要性 在实践中,软件测试的困难常常使人望而却步或敷衍了事,这是由于对测试仍然存在一些不正确的看法和错误的态度,这包括: ①认为测试工作不如设计和编码那样容易取得进展难以给测试人员某种成就感; ②以发现软件错误为目标的测试是非建设性的,甚至是破坏性的,测试中发现错位是对责任者工作的一种否定; ③测试工作枯燥无味,不能引起人们的兴趣; ④测试工作是艰苦而细致的工作; ⑤对自己编写的程序盲目自信,在发现错误后,顾虑别人对自己的开发能力的看法。 这些观点对软件测试工作是极为不利的,必须澄清认识、端正态度,才可能提高软件产品的质量。 (2)测试的目的 如果测试的目的是为了尽可能多地找出错误,那么测试就应该直接针对软件比较复杂的部分或是以前出错比较多的位置。 ①软件测试是为了发现错误而执行程序的过程; ②测试是为了证明程序有错,而不是证明程序无错误; ③一个好的测试用例是在于它能发现至今未发现的错误; ④一个成功的测试是发现了至今未发现的错误的测试。 这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯一目,查找不出错误的测试就是没有价值的,事实并非如此。 首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分析也能帮助我们设计出有针对性地检测方法,改善测试的有效性。其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。 5.2.2测试的步骤 与开发过程类似,测试过程也必须分步骤进行,每个步骤在逻辑上是前一个步骤的继续。大型软件系统通常由若干个子系统组成,每个子系统又由若干个模块组成。因此,大型软件系统的测试基本上由下述几个步骤组成: (1)模块测试在这个测试步骤中所发现的往往是编码和详细设计的错误。 (2)系统测试在这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误。 (3)验收测试在这个测试步骤中发现的往往是系统需求说明书中的错误。 (4)测试汇总表: 用例ID 用例名称 输入描述 预期结果 实际结果 测试数据 1 每日一句 无 符合要求 2 查词模块 输入要查的(中/英)单词 得到单词对应的翻译 得到了单词对应的翻译 Women,中国人 3 翻译模块 输入要翻译的(中/英)句子 得到对应的翻译 得到了对应的翻译 我是中国人; IamaChinese 4 生词本模块 查看和移除生词本中的单词 可以查看和移除生词本中的单词 can 5.3具体模块测试 5.3.1界面反应测试以及触摸测试 测试步骤如下: 2、触摸屏幕上的各个按钮,测试是不是能正常显示以及正常反应 测试结果如下: 图5-3-1界面反应测试以及触摸测试 可以正常进入系统,而且可以正常的进入主界面,依然可以看到主界面的模块。运行结果良好.