Android开发基本流程介绍

上传人:hy****d 文档编号:243134072 上传时间:2024-09-16 格式:PPT 页数:36 大小:728.50KB
返回 下载 相关 举报
Android开发基本流程介绍_第1页
第1页 / 共36页
Android开发基本流程介绍_第2页
第2页 / 共36页
Android开发基本流程介绍_第3页
第3页 / 共36页
点击查看更多>>
资源描述
单击此处编辑母版标题样式。,请您按击鼠标,编辑大纲正文格式。,第二个大纲级,第三个大纲级,第四个大纲级,第五个大纲级,第六个大纲级,第七个大纲级,第八个大纲级,第九个大纲级,单击此处编辑母版标题样式。,单击此处编辑母版文字样式。,第二级,第三级,第四级,第五级,第六级,第七级,第八级,第九级,*,单击此处编辑母版标题样式。,请您按击鼠标,编辑大纲正文格式。,第二个大纲级,第三个大纲级,第四个大纲级,第五个大纲级,第六个大纲级,第七个大纲级,第八个大纲级,第九个大纲级,Android,平台开发简介,平台介绍及开发基本流程,2011-4,月,什么是,Android?,Android,是,Google,在,2007,年,11,月,5,日推出的开源手机操作系统。目前,Android,在中国的发展是 非常火的,为了节省研发费用,国内很多的手机厂商和移动运营商纷纷加入到了,android,阵营,其中包括中国移动,中国联通,中国电信,华为,联想等大企业。在中国不管是知名的手机生产厂商还是山寨手机厂商,都已经开始生产,Android,操作系统的手机。另外,android,应用的范围不仅仅在手机,还被应用在汽车、平板电脑、和智能上网设备上,听说国外已经有了安装有,Android,系统,并且能够上网的智能电饭煲,用户在千里之外就可以操作电饭煲进行煮饭。由于大家大多使用的手机都属傻瓜手机,也就是打打电话、发发短信。从今天开始,大家就应该改变这个观念了,你们需要把智能手机看作是一台电脑,它能完成电脑所能完成的一切。所以你可以像在电脑一样,在智能手机上安装软件,以满足你工作和生活的需要。,2,如何安装,Android SDK,和,Eclipse,插件,所需开发环境,:,JDK 5,或以上版本,(,仅有,JRE,不够,),、,Eclipse 3.4,或以上版本,推荐使用“伽利略”版。,下载用于在,Eclipse,开发,android,应用的,ADT,插件,在企业开发中,很多程序员使用,Eclipse IDE,作为应用的开发环境。为了使得,Android,应用的创建,运行和调试更加方便快捷。,Android,的开发团队专门针对,Eclipse IDE,定制了一个插件:,Android Development Tools,(,ADT,),下载地址:,安装,Eclipse,插件,(ADT),启动,Eclipse,,选择,Help Install New Software,,在出现的对话框里,点击,Add,按钮,在对话框的,name,一栏输入,“ADT”,,然后点击,Archive.,,浏览和选择已经下载的,ADT,插件,压缩文件。,点击,OK.。,返回可用软件的视图,你会看到这个插件,,,然后选择,Developer Tools (,会选中下面的,“Android Developer Tools”,和,“Android Editors“),,点击,Next,,最后重启,Eclipse,。,下载安装,Android SDK,:,Android SDK,包含了开发,Android,应用所依赖的,jar,文件、运行环境及相关工具。,下载地址:,下载完,SDK,后,把,.zip,文件解压到你电脑上合适位置。启动,Eclipse,,选择,window-preferences,,在打开的视图左边点击,android,,在右边的,SDK Location,中选择,Android SDK,所在位置。,3,开发第一个,Android,应用,打开,Eclipse,,新建项目,(,点击,File,NewProject,),,在项目列表中展开,Android,目录,选择,Android Project,,如下图:,4,开发第一个,Android,应用,5,开发第一个,Android,应用,点击”,finish”,即可完成项目的创建,创建后的项目已经是一个可运行的,Android,应用,我们可以通过下面方式运行此应用:,点击工具栏上机器人形状的虚拟设备管理器(简称“,AVD“,),如下:,6,开发第一个,Android,应用,7,“,尚未注册网络”错误信息的解决办法,打开,Android,模拟器时,出现无信号,拔打电话或发短信时,提示“尚未注册网络”错误信息的解决方案如下。,场景一:你的电脑没有连接上互联网,同时也没有在局域网。,解决办法:右键点击网上邻居,选择,属性,在网络连接窗口中右键点击,本地连接,选择,属性,设置,TCP/IP,属性如下,:,IP,地址,:192.168.1.100,子网掩码,:255.255.255.0,默认网关,:192.168.1.100,首选,DNS,服务器,:192.168.1.100,场景二:你的电脑没有连接上互联网,但在局域网。,解决办法:右键点击网上邻居,选择,属性,在网络连接窗口中右键点击,本地连接,选择,属性,设置,TCP/IP,属性如下,:,IP,地址,:,设置成你所在局域网的,IP,,如:,192.168.1.100,子网掩码,:,设置成你所在局域网的掩码,如:,255.255.255.0,默认网关,:,设置成你所在局域网的网关,一般网关的,IP,格式为:*,.*.*.1,,如:,192.168.1.1,首选,DNS,服务器,:,设置成你所在局域网的路由器,IP,,一般路由器的,IP,格式为:*,.*.*.1,,如:,192.168.1.1,最后一种解决方案是:让你的电脑连接上互联网。,8,开发第一个,Android,应用,在项目上右键点击,run as,Android application,,如下图,:,9,Android,应用程序架构,src/ java,原代码存放目录,gen/,自动生成目录,gen,目录中存放所有由,Android,开发工具自动生成的文件。目录中最重要的就是,R.java,文件。 这个文件由,Android,开发工具自动产生的。,Android,开发工具会自动根据你放入,res,目录的,xml,界面文件、图标与常量,同步更新修改,R.java,文件。正因为,R.java,文件是由开发工具自动生成的,所以我们应避免手工修改,R.java,。,R.java,在应用中起到了字典的作用,它包含了界面、图标、常量等各种资源的,id,,通过,R.java,,应用可以很方便地找到对应资源。另外编绎器也会检查,R.java,列表中的资源是否被使用到,没有被使用到的资源不会编绎进软件中,这样可以减少应用在手机占用的空间。,res/,资源,(Resource),目录,在这个目录中我们可以存放应用使用到的各种资源,如,xml,界面文件,图片或数据。,assets,资源目录,Android,除了提供,/res,目录存放资源文件外,在,/,assets,目录也可以存放资源文件,而且,/,assets,目录下的资源文件不会在,R.java,自动生成,ID,,,所以读取,/,assets,目录下的文件必须指定文件的路径,如:,AndroidManifest.xml,项目清单文件,这个文件列出了应用程序所提供的功能,以后你开发好的各种组件需要在该文件中进行配置,如果应用使用到了系统内置的应用,(,如电话服务、互联网服务、短信服务、,GPS,服务等等,),,你还需在该文件中声明使用权限。,default.properties,项目环境信息,,一般是不需要修改此文件,10,Android,中的显示单位,px (pixels),像素,一般,HVGA,代表,320x480,像素,这个用的比较多。,dip,或,dp (device independent pixels),设备独立像素,这个和设备硬件有关,一般为了支持,WVGA,、,HVGA,和,QVGA,推荐使用这个,不依赖像素。,sp (scaled pixels best for text size),比例像素,主要处理字体的大小,可以根据系统的字体自适应。,除了上面三个显示单位,下面还有几个不太常用:,in (inches),英寸,mm (millimeters),毫米,pt (points),点,,1/72,英寸,为了适应不同分辨率,不同的像素密度,推荐使用,dip,,文字使用,sp,。,11,Android,开发平台是开放的平台,而位于四层框架顶端的应用开发,必然涉及到,Android,组件。本文将为大家详细介绍,Android,组件。,组件(,Component,),在谈及所谓架构和重用的时候,是一个重要的事情。很多时候都会说基于组件的软件架构,指的是期望把程序做乐高似的,有一堆接口标准封装完整的组件放在哪里,想用的时候取上几个一搭配,整个程序就构建完成了。,在开篇的时候就在说,,Android,是一个为组件化而搭建的平台,它引入所谓,Mash-Up,的概念,这使得你在应用的最上层,想做的不组件化都是很困难的一件事,具体说来,,Android,有四大组件:,Activity,、,Service,、,Broadcast Receiver,、,Content Provider,。,Android,四大组建,12,Activity,是为用户操作而展示的可视化用户界面。比如说,一个,activity,可以展示一个菜单项列表供用户选择,或者显示一些包含说明的照片。一个短消息应用程序可以包括一个用于显示做为发送对象的联系人的列表的,activity,,一个给选定的联系人写短信的,activity,以及翻阅以前的短信和改变设置的,activity,。尽管它们一起组成了一个内聚的用户界面,但其中每个,activity,都与其它的保持独立。每个都是以,Activity,类为基类的子类实现。,一个应用程序可以只有一个,activity,,或者,如刚才提到的短信应用程序那样,包含很多个。每个,activity,的作用,以及其数目,自然取决于应用程序及其设计。一般情况下,总有一个应用程序被标记为用户在应用程序启动的时候第一个看到的。从一个,activity,转向另一个的方式是靠当前的,activity,启动下一个。,每个,activity,都被给予一个默认的窗口以进行绘制。一般情况下,这个窗口是满屏的,但它也可以是一个小的位于其它窗口之上的浮动窗口。一个,activity,也可以使用超过一个的窗口比如,在,activity,运行过程中弹出的一个供用户反应的小对话框,或是当用户选择了屏幕上特定项目后显示的必要信息。,窗口显示的可视内容是由一系列视图构成的,这些视图均继承自,View,基类。每个视图均控制着窗口中一块特定的矩形空间。父级视图包含并组织它子视图的布局。叶节点视图(位于视图层次最底端)在它们控制的矩形中进行绘制,并对用户对其直接操作做出响应。所以,视图是,activity,与用户进行交互的界面。比如说,视图可以显示一个小图片,并在用户指点它的时候产生动作。,Android,有很多既定的视图供用户直接使用,包括按钮、文本域、卷轴、菜单项、复选框等等。,Activity,活动,13,服务没有可视化的用户界面,而是在一段时间内在后台运行。比如说,一个服务可以在用户做其它事情的时候在后台播放背景音乐、从网络上获取一些数据或者计算一些东西并提供给需要这个运算结果的,activity,使用。每个服务都继承自,Service,基类。,一个媒体播放器播放播放列表中的曲目是一个不错的例子。播放器应用程序可能有一个或多个,activity,来给用户选择歌曲并进行播放。然而,音乐播放这个任务本身不应该为任何,activity,所处理,因为用户期望在他们离开播放器应用程序而开始做别的事情时,音乐仍在继续播放。为达到这个目的,媒体播放器,activity,应该启用一个运行于后台的服务。而系统将在这个,activity,不再显示于屏幕之后,仍维持音乐播放服务的运行。,你可以连接至(绑定)一个正在运行的服务(如果服务没有运行,则启动之)。连接之后,你可以通过那个服务暴露出来的接口与服务进行通讯。对于音乐服务来说,这个接口可以允许用户暂停、回退、停止以及重新开始播放。,如同,activity,和其它组件一样,服务运行于应用程序进程的主线程内。所以它不会对其它组件或用户界面有任何干扰,它们一般会派生一个新线程来进行一些耗时任务(比如音乐回放)。,Service,服务和接收器,14,广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播比如说,通知其它应用程序一些数据下载完成并处于可用状态。,应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自,BroadcastReceiver,基类。广播接收器没有用户界面。然而,它们可以启动一个,activity,来响应它们收到的信息,或者用,NotificationManager,来通知用户。通知可以用很多种方式来吸引用户的注意力闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。,Broadcast Receiver,接收器,15,内容提供者将一些特定的应用程序数据供给其它应用程序使用。数据可以存储于文件系统、,SQLite,数据库或其它方式。内容提供者继承于,ContentProvider,基类,为其它应用程序取用和存储它管理的数据实现了一套标准方法。然而,应用程序并不直接调用这些方法,而是使用一个,ContentResolver,对象,调用它的方法作为替代。,ContentResolver,可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理。,参阅独立的内容提供者章节获得更多关于使用内容提供者的内容。,每当出现一个需要被特定组件处理的请求时,,Android,会确保那个组件的应用程序进程处于运行状态,或在必要的时候启动它。并确保那个相应组件的实例的存在,必要时会创建那个实例。,Content Provider,16,当接收到,ContentResolver,发出的请求后,内容提供者被激活。而其它三种组件,activity,、服务和广播接收器被一种叫做,intent,的异步消息所激活。,intent,是一个保存着消息内容的,Intent,对象。对于,activity,和服务来说,它指明了请求的操作名称以及作为操作对象的数据的,URI,和其它一些信息。比如说,它可以承载对一个,activity,的请求,让它为用户显示一张图片,或者让用户编辑一些文本。而对于广播接收器而言,,Intent,对象指明了声明的行为。比如,它可以对所有感兴趣的对象声明照相按钮被按下。,对于每种组件来说,激活的方法是不同的:,通过传递一个,Intent,对象至,Context.startActivity(),或,Activity.startActivityForResult(),以载入(或指定新工作给)一个,activity,。相应的,activity,可以通过调用,getIntent(),方法来查看激活它的,intent,。,Android,通过调用,activity,的,onNewIntent(),方法来传递给它继发的,intent,。一个,activity,经常启动了下一个。如果它期望它所启动的那个,activity,返回一个结果,它会以调用,startActivityForResult(),来取代,startActivity(),。比如说,如果它启动了另外一个,activity,以使用户挑选一张照片,它也许想知道哪张照片被选中了。结果将会被封装在一个,Intent,对象中,并传递给发出调用的,activity,的,onActivityResult(),方法。,组件的连接者,-Intent,17,通过传递一个,Intent,对象至,Context.startService(),将启动一个服务(或给予正在运行的服务以一个新的指令)。,Android,调用服务的,onStart(),方法并将,Intent,对象传递给它。与此类似,一个,Intent,可以被调用组件传递给,Context.bindService(),以获取一个正在运行的目标服务的连接。这个服务会经由,onBind(),方法的调用获取这个,Intent,对象(如果服务尚未启动,,bindService(),会先启动它)。比如说,一个,activity,可以连接至前述的音乐回放服务,并提供给用户一个可操作的(用户界面)以对回放进行控制。这个,activity,可以调用,bindService(),来建立连接,然后调用服务中定义的对象来影响回放。,应用程序可以凭借将,Intent,对象传递给,Context.sendBroadcast(),,,Context.sendOrderedBroadcast(),, 以及,Context.sendStickyBroadcast(),和其它类似方法来产生一个广播。,Android,会调用所有对此广播有兴趣的广播接收器的,onReceive(),方法,将,intent,传递给它们。,18,Manifest,文件,当,Android,启动一个应用程序组件之前,它必须知道那个组件是存在的。所以,应用程序会在一个,manifest,文件中声明它的组件,这个文件会被打包到,Android,包中。这个,.apk,文件还将涵括应用程序的代码、文件以及其它资源。,这个,manifest,文件以,XML,作为结构格式,而且对于所有应用程序,都叫做,AndroidManifest.xml,。为声明一个应用程序组件,它还会做很多额外工作,比如指明应用程序所需链接到的库的名称(除了默认的,Android,库之外)以及声明应用程序期望获得的各种权限。,但manifest文件的主要功能仍然是向Android声明应用程序的组件。举例说明,一个activity可以如下声明:,元素的name属性指定了实现了这个activity的,Activity,的子类。icon和label属性指向了包含展示给用户的此activity的图标和标签的资源文件。,其它组件也以类似的方法声明,元素用于声明服务,,元素用于声明广播接收器,而,元素用于声明内容提供者。 manifest,文件中未进行声明的,activity,、服务以及内容提供者将不为系统所见,从而也就不会被运行。然而,广播接收器既可以在,manifest,文件中声明,也可以在代码中进行动态的创建,并以调用,Context.registerReceiver(),的方式注册至系统。,19,如前所述,一个,activity,可以启动另外一个,甚至包括与它不处于同一应用程序之中的。举个例子说,假设你想让用户看到某个地方的街道地图。而已经存在一个具有此功能的,activity,了,那么你的,activity,所需要做的工作就是把请求信息放到一个,Intent,对象里面,并把它传递给,startActivity(),。于是地图浏览器就会显示那个地图。而当用户按下,BACK,键的时候,你的,activity,又会再一次的显示在屏幕上。,对于用户来说,这看起来就像是地图浏览器是你,activity,所在的应用程序中的一个组成部分,其实它是在另外一个应用程序中定义,并运行在那个应用程序的进程之中的。,Android,将这两个,activity,放在同一个任务中来维持一个完整的用户体验。简单的说,任务就是用户所体验到的“应用程序”。它是安排在一个堆栈中的一组相关的,activity,。堆栈中的根,activity,就是启动了这整个任务的那个一般情况下,它就是用户在应用程序加载器中所选择的。而堆栈最上方的,activity,则是当前运行的用户直接对其进行操作的。当一个,activity,启动另外一个的时候,新的,activity,就被压入堆栈,并成为当前运行的,activity,。而前一个,activity,仍保持在堆栈之中。当用户按下,BACK,键的时候,当前,activity,出栈,而前一个恢复为当前运行的,activity,。,Activity,和任务,20,Activity,生命周期,21,用户界面User Interface,在一个,Android,应用中,用户界面是由,View,和,ViewGroup,对象构建的。,View,与,ViewGroup,都有很多种类,而它们都是,View,类的子类。,View,View,对象是,Android,平台中用户界面体现的基础单位。,View,类是它称为“,widgets,(工具)”的子类的基础,它们提供了诸如文本输入框和按钮之类的,UI,对象的完整实现。,ViewGroup,类同样为其被称为“,Layouts,(布局)”的子类奠定了基础,它们提供了象流式布局、表格布局以及相对布局之类的布局架构。,View,对象是一个数据体,它的属性存储了用于屏幕上一块矩形区域的布局参数及内容。并负责这块它所辖的这个矩形区域之中所有测量、布局、焦点转换、卷动以及按键,/,触摸手势的处理。作为一个用户界面对象,,View,同时也担任着用户交互关键点以及交互事件接受者的角色。,22,布局,Layout,定义并展现你的视图层次的最常用的方法是使用,XML,布局文件。如同,HTML,一样,,XML,为布局提供了一种可读的结构。,XML,中的每个元素都是,View,或,ViewGroup,对象(抑或它们的子类)。,View,对象是树的叶节点,而,ViewGroup,对象是树的分支(参阅楼上的视图层次图)。,XML,元素的名称与它体现的,Java,类相对应。所以一个,元素将在你的,UI,中生成一个,TextView,,而,则创建一个,LinearLayout,视图组。当你载入一个布局资源时,,Android,系统会根据你布局中的元素初始化这些运行时对象。,举例来说,一个包含文本视图和一个按钮的简单垂直布局如下:,请注意:,LinearLayout,元素包含了,TextView,和,Button,对象。你可以在其中另外安置一个,LinearLayout,(或其它类型的视图组),以延展这个视图层次,构建更复杂的布局。,23,用户界面事件,UI Events,当你在用户界面中加入了一些视图和工具之后,你可能想要知道如何让它们与用户交互,进而实现你的动作。如欲获得用户界面事件通知,你需要做以下两件事情之一:,定义一个事件侦听器并将其注册至视图。通常情况下,这是你侦听事件的主要方式。,View,类包含了一大堆命名类似,OnListener,的接口,每个都带有一个叫做,On(),的回调方法。比如:,View.OnClickListener,(用以处理视图中的点击),,View.OnTouchListener,(用以处理视图中的触屏事件),以及,View.OnKeyListener,(用以处理视图中的设备按键事件)。所以,如果你希望你的视图在它被”点击”(比如选择了一个按钮)的时候获得通知,你就要实现,OnClickListener,,定义它的,onClick(),回调方法(在其中进行相应处理),并将它用,setOnClickListener(),方法注册到视图上。,为视图覆写一个现有的回调方法。这种方法主要用于你自己实现了一个,View,类,并想侦听其上发生的特定事件。比如说当屏幕被触摸(,onTouchEvent(),),当轨迹球发生了移动(,onTrackballEvent(),)或者是设备上的按键被按下(,onKeyDown(),)。这种方式允许你为自己定制的视图中发生的每个事件定义默认的行为,并决定是否需要将事件传递给其它的子视图。再说一次,这些是,View,类相关的回调方法,所以你只能在你构建自定义组件时定义它们。,如何在视图中处理用户交互请参见处理用户界面事件文档。,24,资源和资产,Resources and Assets,资源是,Android,应用程序不可或缺的部分。总体而言,资源是你想包含和引入到应用程序里面的一些外部元素,比如图片、音频、视频、文本字符串、布局、主题等。每个,Android,应用程序包含一个资源目录(,res/,)和资产目录(,assets/,),资产不经常被使用,因为它们的应用程序很少。你仅在需要读取原始字节流时才需要保存数据为资产。资源和资产目录均驻留在,Android,项目树的顶端,和源代码目录(,src/,)处在同一级上。,资源和资产从表面上看没多大区别,不过总体上,在存储外部内容时资源用得更多。真正的区别在于任何放置在资源目录里的内容可以通过您的应用程序的,R,类访问,这是被,Android,编译过的。而任何存放在资产目录里的内容会保持它的原始文件格式,为了读取它,你必须使用,AssetManager,来以字节流的方式读取文件。所以保持文件和数据在资源中(,res/,)中会更方便访问。,25,目录,Directory,资源类型,Resource Types,res/anim/XML,文件,它们被编译进逐帧动画(,frame by frame animation,)或补间动画(,tweened animation,)对象,res/drawable/.png,、,.9.png,、,.jpg,文件,它们被编译进以下的,Drawable,资源子类型中:,要获得这种类型的一个资源,可以使用,Resource.getDrawable(id),位图文件,9-patches,(可变尺寸的位图),为了获取资源类型,使用,mContext.getResources().getDrawable(R.drawable.imageId),注意:放在这里的图像资源可能会被,aapt,工具自动地进行无损压缩优化。比如,一个真彩色但并不需要,256,色的,PNG,可能会被转换为一个带调色板的,8,位,PNG,。这使得同等质量的图片占用更少的资源。所以我们得意识到这些放在该目录下的二进制图像在生成时可能会发生变化。如果你想读取一个图像位流并转换成一个位图,(bitmap),,请把图像文件放在,res/raw/,目录下,这样可以避免被自动优化。,res/layout/,被编译为屏幕布局(或屏幕的一部分)的,XML,文件。参见布局声明(,Declaring Layout,),26,res/values/,可以被编译成很多种类型的资源的,XML,文件。,注意,:,不像其他的,res/,文件夹,它可以保存任意数量的文件,这些文件保存了要创建资源的描述,而不是资源本身。,XML,元素类型控制这些资源应该放在,R,类的什么地方。,尽管这个文件夹里的文件可以任意命名,不过下面使一些比较典型的文件(文件命名的惯例是将元素类型包含在该名称之中):,array.xml,定义数据,colors.xml,定义,color drawable,和颜色的字符串值(,color string values,)。使用,Resource.getDrawable(),和,Resources.getColor(),分别获得这些资源。,dimens.xml,定义尺寸值(,dimension value,)。使用,Resources.getDimension(),获得这些资源。,strings.xml,定义字符串(,string,)值(使用,Resources.getString(),或者,Resources.getText(),获取这些资源。,getText(),会保留在,UI,字符串上应用的丰富的文本样式)。,styles.xml,定义样式(,style,)对象。,res/xml/,任意的,XML,文件,在运行时可以通过调用,Resources.getXML(),读取。,res/raw/,直接复制到设备中的任意文件。它们无需编译,添加到你的应用程序编译产生的压缩文件中。要使用这些资源,可以调用,Resources.openRawResource(),,参数是资源的,ID,,即,R.raw.some,。,27,数据存储与访问,很多时候我们的软件需要对处理后的数据进行存储或再次访问。,Android,为数据存储提供了多种方式,分别有如下几种:,文件,SharedPreferences(,参数,),SQLite,数据库,内容提供者(,Content provider,),网络,28,使用文件进行数据存储,首先给大家介绍使用文件如何对数据进行存储,,Activity,提供了,open(),方法可以用于把数据输出到文件中,具体的实现过程与在,J2SE,环境中保存数据到文件中是一样的。,public class extends Activity ,Override public void onCreate(Bundle savedInstanceState) ,.,outStream = this.open(itcast.txt, Context.MODE_PRIVATE);,outStream.write(“ggggg.getBytes();,outStream.close();,open(),方法的第一参数用于指定文件名称,不能包含路径分隔符“,/”,,如果文件不存在,,Android,会自动创建它。创建的文件保存在,/data/data/files,目录,如:,/data/data/cn.itcast.action/,,通过点击,Eclipse,菜单“,Window”-“Show View”-“Other”,,在对话窗口中展开,android,文件夹,选择下面的视图,然后在视图中展开,/data/data/files,目录就可以看到该文件。,open(),方法的第二参数用于指定操作模式,有四种模式,分别为:,Context.MODE_PRIVATE = 0,Context.MODE_APPEND = 32768,Context.MODE_WORLD_READABLE = 1,Context.MODE_WORLD_WRITEABLE = 2,29,使用文件进行数据存储,Context.MODE_PRIVATE,:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用,Context.MODE_APPEND,Context.MODE_APPEND,:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。,Context.MODE_WORLD_READABLE,和,Context.MODE_WORLD_WRITEABLE,用来控制其他应用是否有权限读写该文件。,MODE_WORLD_READABLE,:表示当前文件可以被其他应用读取;,MODE_WORLD_WRITEABLE,:表示当前文件可以被其他应用写入。,如果希望文件被其他应用读和写,可以传入:,open(itcast.txt, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);,android,有一套自己的安全模型,当应用程序,(.apk),在安装时系统就会分配给他一个,userid,,当该应用要去访问其他资源比如文件的时候,就需要,userid,匹配。默认情况下,任何应用创建的文件,,sharedpreferences,,数据库都应该是私有的(位于,/data/data/files,),其他程序无法访问。除非在创建时指定了,Context.MODE_WORLD_READABLE,或者,Context.MODE_WORLD_WRITEABLE,,只有这样其他程序才能正确访问。,30,使用,SharedPreferences,进行数据存储,很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的,QQ,,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是,window,软件通常我们会采用,ini,文件进行保存,如果是,j2se,应用,我们会采用,properties,属性文件或者,xml,进行保存。如果是,Android,应用,我们最适合采用什么方式保存软件配置参数呢?,Android,平台给我们提供了一个,SharedPreferences,类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用,SharedPreferences,保存数据,其背后是用,xml,文件存放数据,文件存放在,/data/data/shared_prefs,目录下:,SharedPreferences sharedPreferences = getSharedPreferences(itcast, Context.MODE_PRIVATE);,Editor editor = sharedPreferences.edit();/,获取编辑器,editor.putString(name, ,传智播客,);,editor.putInt(age, 4);,mit();/,提交修改,生成的,itcast.xml,文件内容如下:,传智播客,因为,SharedPreferences,背后是使用,xml,文件保存数据,,getSharedPreferences(name,mode),方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由,Android,自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。如果希望,SharedPreferences,背后使用的,xml,文件能被其他应用读和写,可以指定,Context.MODE_WORLD_READABLE,和,Context.MODE_WORLD_WRITEABLE,权限。,另外,Activity,还提供了另一个,getPreferences(mode),方法操作,SharedPreferences,,这个方法默认使用当前类不带包名的类名作为文件的名称。,31,访问,SharedPreferences,中的数据,访问,SharedPreferences,中的数据代码如下:,SharedPreferences sharedPreferences = getSharedPreferences(itcast, Context.MODE_PRIVATE);,/getString(),第二个参数为缺省值,如果,preference,中不存在该,key,,将返回缺省值,String name = sharedPreferences.getString(name, );,int age = sharedPreferences.getInt(age, 1);,如果访问其他应用中的,Preference,,前提条件是:该,preference,创建时指定了,Context.MODE_WORLD_READABLE,或者,Context.MODE_WORLD_WRITEABLE,权限。如:有个,为,cn.itcast.action,的应用使用下面语句创建了,preference,。,getSharedPreferences(itcast, Context.,MODE_WORLD_READABLE);,其他应用要访问上面应用的,preference,,,首先需要创建上面应用的,Context,,然后通过,Context,访问,preference,,访问,preference,时会在应用所在包下的,shared_prefs,目录找到,preference,:,Context otherAppsContext = createPackageContext(cn.itcast.action, Context.,CONTEXT_IGNORE_SECURITY,);,SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences(itcast, Context.MODE_WORLD_READABLE);,String name = sharedPreferences.getString(name, );,int age = sharedPreferences.getInt(age, 0);,如果不通过创建,Context,访问其他应用的,preference,,也可以以读取,xml,文件方式直接访问其他应用,preference,对应的,xml,文件,如:,= new File(“/data/data/shared_prefs/itcast.xml”);/,应替换成应用的包名,32,使用嵌入式关系型,SQLite,数据库存储数据,除了可以使用文件或,SharedPreferences,存储数据,还可以选择使用,SQLite,数据库存储数据。,在,Android,平台上,集成了一个嵌入式关系型数据库,SQLite,,,SQLite3,支持,NULL,、,INTEGER,、,REAL,(浮点数字)、,TEXT(,字符串文本,),和,BLOB(,二进制对象,),数据类型,虽然它支持的类型只有五种,但实际上,sqlite3,也接受,varchar(n),、,char(n),、,decimal(p,s),等数据类型,只不过在运算或保存时会转成对应的五种数据类型。,SQLite,最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在,Integer,类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。 但有一种情况例外:定义为,INTEGER PRIMARY KEY,的字段只能存储,64,位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。 另外,,SQLite,在解析,CREATE TABLE,语句时,会忽略,CREATE TABLE,语句中跟在字段名后面的数据类型信息,如下面语句会忽略,name,字段的类型信息:,CREATE TABLE person (personid integer primary key autoincrement, name varchar(20),SQLite,可以解析大部分标准,SQL,语句,如:,查询语句:,select * from,表名,where,条件子句,group by,分组字句,having . order by,排序子句,如:,select * from person,select * from person order by id desc,select name from person group by name having count()1,分页,SQL,与,mysql,类似,下面,SQL,语句获取,5,条记录,跳过前面,*3,条记录,select * from Account limit 5 offset 3,或者,select * from Account limit 3,5,插入语句:,insert into,表名,(,字段列表,) values(,值列表,),。如:,insert into person(name, age) values(,传智,3),更新语句:,update,表名,set,字段名,=,值,where,条件子句。如:,update person set name=,传智,where id=10,删除语句:,delete from,表名,where,条件子句。如:,delete from person where id=10,33,使用,SQLiteOpenHelper,对数据库进行版本管理,我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了,SQLite,数据库,我们必须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在,Android,系统,为我们提供了一个名为,SQLiteOpenHelper,的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理来实现前面提出的需求。,为了实现对数据库版本进行管理,,SQLiteOpenHelper,类提供了两个重要的方法,分别是,onCreate(SQLiteDatabase db),和,onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),,前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用,SQLiteOpenHelper,的,getWritableDatabase(),或者,getReadableDatabase(),方法获取用于操作数据库的,SQLiteDatabase,实例的时候,如果数据库不存在,,Android,系统会自动生成一个数据库,接着调用,onCreate(),方法,,onCreate(),方法在初次生成数据库时才会被调用,在,onCreate(),方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。,onUpgrade(),方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是,1,,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为,2(,有同学问设置为,3,行不行?当然可以,如果你愿意,设置为,100,也行,),,并且在,onUpgrade(),方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在,onUpgrade(),方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。,getWritableDatabase(),和,getReadableDatabase(),方法都可以获取一个用于操作数据库的,SQLiteDatabase,实例。但,getWritableDatabase(),方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是,getWritableDatabase(),方法就会出错。,getReadableDatabase(),方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。,34,使用,SQLiteOpenHelper,对数据库进行版本管理,public class DatabaseHelper extends SQLiteOpenHelper ,/,类没有实例化,是不能用作父类构造器的参数,必须声明为静态,private static final String name = “itcast; /,数据库名称,private static final int version = 1; /,数据库版本,public DatabaseHelper(Context context) ,/,第三个参数,CursorFactory,指定在执行查询时获得一个游标实例的工厂类,设置为,null,代表使用系统默认的工厂类,super(context, name, null, version);,Override public void onCreate(SQLiteDatabase db) ,db.execSQL(CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER);,Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) ,/.,35,完,谢谢,.,36,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!