Android开发笔记.docx
《Android开发笔记.docx》由会员分享,可在线阅读,更多相关《Android开发笔记.docx(15页珍藏版)》请在冰豆网上搜索。
![Android开发笔记.docx](https://file1.bdocx.com/fileroot1/2023-5/26/218ef761-0516-48d6-ac8d-db8ced0a5182/218ef761-0516-48d6-ac8d-db8ced0a51821.gif)
Android开发笔记
Android开发速览
——为资深java程序员提供一个概览Android开发特点的快速通道
目录
1Hello,World!
2
2Android应用的特色类3
2.1应用的三种重要组件3
2.2SQLiteDatabase4
2.3ContentProvider和ContentResolver4
2.4Intent和Bundle4
3用户界面组件体系5
4事件处理6
5Activity和Fragment7
5.1Activity的生命周期和相关回调方法7
5.2Activity的子类和层次结构8
5.3Activity的调用和加载8
5.4Fragment9
6图像处理10
6.1使用Drawable资源10
6.2绘图10
6.3动画11
7数据处理11
7.1支持少量数据存取的SharedPreferences11
7.2读写SD卡的文件12
7.3使用SQLite数据库12
7.4ContentProvider13
8GPS开发13
1Hello,World!
Android使用Java作为开发语言,基本类库完全一致,所不同的仅是对UI部分,对Java程序员的门槛很低,相当于熟悉一套新的Awt/Swing。
同时,由于针对特定的操作系统(Android),不用再考虑跨平台问题,Android的UI能力得到了很大的增强,开发起来很爽。
Android的页面布局增加了xml配置的方式,使布局代码和应用逻辑进行了分离,提高了编程效率。
页面布局配置使用IDE提供的图形工具,可以用可视化的方法拖动控件完成布局,并在右侧的属性栏中直接设置常规属性,避免了大量的记忆和查阅API的工作,效率很高。
下面是一个经典的HelloWorld示例。
packagenra.android.hello;
publicclassMainActivityextendsActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
这个示例实际包括了两部分内容。
第一部分是所编写的源代码(实际也是IDE生成的)nra.android.hello类,即所给出部分。
该部分实现了一个Activity(类似于Java的JFrame)的子类,并通过继承自Activity的setContentView方法设置了主窗口。
Android程序的一个特点,是不再需要main方法作为应用入口点,而代之以在清单文件AndroidManifest中指定执行类。
文中的MainActivity类即被指定为执行类。
Android程序的另一个特点,是应用资源和代码的分离。
上述例子中出现的“R”,就是工具为应用生成的资源引用类,是沟通应用和资源的桥梁。
应用资源作为独立的文件,放置在res目录中。
该目录由多个子目录,这些子目录代表应用资源的四大类别:
1.layout。
定义应用的布局,即前面讲到的xml配置文件(activity_main.xml)。
配置文件也负责指定应用的执行点:
实际上,activity_main.xml的地位甚至要高过MainActivity.java,因为要在配置文件中定义哪个类是入口类。
2.menu。
定义应用使用的菜单。
3.drawable。
定义应用中使用的所有“可画出”的东西。
通常是图片。
Android要适应不同手机屏幕的需要,要保存不同分辨率的图像版本,因此drawable资源实际为以drawable开头的一组目录。
4.values。
定义应用中使用的字符串、维度(Dimension)等。
将这些内容作为资源定义,可以更好地让内容与代码分离。
values同样涉及到适应不同屏幕(如Dimension)的问题,因此也是一组目录。
为方便开发者引用资源,开发工具为应用自动生成一个资源描述类R,可以通过它得到所有对资源的引用。
如上例中,页面布局配置文件作为一种资源,由R.layout.activity_main对它进行了引用,并赋给了主窗口的视图。
Android程序运行,需使用AVD(AndroidVirtualDevice)。
AVD提供了一个模拟手机的环境,采取类似操作手机的方式控制程序运行。
注意:
Android程序中的System.out.print输出,不显示在IDE的console窗口,而显示在LogCat窗口中。
2Android应用的特色类
2.1应用的三种重要组件
Activity:
一个独立的用户界面,类似java的JFrame或JSP。
普通应用都是从建立Activity的子类开始的。
Service:
在后台运行,没有用户界面的程序。
BroadcastReceiver:
广播消息处理应用,接收Android系统中其它应用的消息,并进行处理。
可以利用BoardcastReceiver实现不同组件间的通信。
Activity可以通过bindService()方法与Service绑定,从而实现方法调用和数据通信。
也可以通过startService()方法启动Service。
Activity可以通过sendBroadcast()方法发送广播消息,实现与BroadcastReceiver的通信。
Service与它所在的应用处于同一进程,不会单独启动一个进程,因此不能在Service中处理耗时的任务。
处理耗时任务需要启动新线程。
此时可以使用其子类IntentService。
IntentService会创建单独的worker线程来处理所有的Intent请求,无需开发者处理多线程问题。
2.2SQLiteDatabase
Android提供了一个轻量的、基于文件的数据库SQLite。
SQLiteDatabase封装了对该数据库的访问API,使开发者可以轻松访问本地数据库。
2.3ContentProvider和ContentResolver
Android的应用是相互独立的,各自运行在自己的Dalvid(Android平台的Java虚拟机)中。
ContentProvider和ContentResolver(ContentProvider是数据服务提供者,ContentResolver相当于ContentProvider的远端代理)实现了一组标准的方法,可以通过Uri实现数据访问,从而能够让其他应用程序保存或读取此内容提供者处理的各种数据类型。
2.4Intent和Bundle
Android的组件间相互调用时,不直接通过组件名,而是通过Intent类型的参数进行调用,以实现程序间的解耦。
例如Activity有startActivity(Intent)方法,Service有startService(Intent)方法等。
Intent封装了“调用意图”。
调用意图可以直接给出被调用者的名字,也可以给出被调用者的条件,由系统负责寻找满足条件的组件(解耦!
)。
Intent还可以在调用方之间传递数据。
所携带数据可以是简单的key-value(key是字符串,value是原始类型)形式,也可以是数据包Bundle形式。
两种参数均使用Intent的put/get(XXX)Extras方法(XXX表示get“key-value”参数时所取值的类型)。
Bundle是个封装了多个数据的数据包,其元素还是key-value形式,但value可以是任何实现了Serializable的对象。
取放参数的方法分别是getXXX、getSerializable和putXXX、putSerializable。
Intent的putExtras方法还具有智能性!
当已存在Bundle对象时,putExtras会自动将对象放在Bundle中!
3用户界面组件体系
Android应用的绝大部分UI组件都放在android.widget、android.view及其子包中。
View是所有UI组件的祖先,它类似于JPanel,代表一个空白的矩形区域。
View的重要子类包括:
1.ViewGroup。
作为其它组件的容器使用。
Android的布局管理器都是的ViewGroup子类。
2.TextView。
代表文本框,类似JLabel,但功能很强大,具有将指定格式文本自动转换为超链接、设置文本框关联的输入法等功能。
所有文本框类组件都是它的子类,包括编辑框、检查框、各类按钮。
3.ImageView。
用于显示图片等任何可画出(Drawable)的东西。
Android用android.graphics.drawable.Drawable类是所有可画出的东西的基类。
4.AdaptView。
表示列表项,包括ListView、GridView、Spinner(列表选择框,不同于Swing的Spinner)。
5.ProgressBar。
进度条,包括Horizontal(水平进度条)、Inverse(环形进度条)、SeekBar(拖动条)和RatingBar(星级评分条)等。
6.ViewAnimator。
产生动画效果的基类。
ViewAnimator继承自FrameLayout,可以将多个View“叠”在一起,切换时体现出动画效果。
7.杂项组件。
a)Toast。
信息提示框。
在屏幕上显示信息,但不会成为焦点,而且会自动消失。
b)CalendarView。
日历视图。
c)DatePicker和TimePicker。
日期和时间选择器。
d)NumberPicker。
数值选择器。
e)SearchView。
搜索框,允许通过监听器查看用户输入,并在完成输入后执行实际的搜索。
f)TabHost。
选项卡。
g)ScrollView。
滚动视图,为组件添加垂直滚动条。
h)Notification。
在手机通知栏(最上面显示电池电量等信息的地方)显示信息。
i)ActionBar。
活动条,位于传统标题栏的位置,可显示应用图标、Activity标题和活动项。
8.对话框。
包括:
a)AlertDialog。
功能丰富、实际应用最广的对话框。
b)ProgressDialog。
对进度条的简单封装。
c)DatePickerDialog和TimePickerDialog。
对日期和时间选择器的封装。
9.菜单。
包括选项菜单(OptionMenu)和上下文菜单(ContextMenu)。
OptionMenu在单击手机菜单键时显示,ContextMenu在长按某个组件时显示。
4事件处理
Android事件处理号称有两种方式:
基于回调的方式和基于监听的方式。
两种方式的本质是相同的,不同的只是实现方法。
基于监听的方法与传统java相同,需要听过add...Listener方法设置监听器;基于回调的方法则是通过重写Activity的事件处理方法实现。
可见,回调方法更适合处理通用事件,可以一个方法包打天下;监听方法更适合处理个性事件,更符合OO编程思想。
监听机制涉及三类对象:
事件源(EventSource)、事件(Event)和事件监听器(EventListener)。
代码风格和传统java完全相同。
回调机制在编程上更加简单,只需重写Activity的事件处理方法即可。
可重写的方法基本都是键盘和触碰响应方法,包括:
1.booleanonKeyDown(intkeyCode,KeyEventevent)
2.booleanonKeyLongPress(intkeyCode,KeyEventevent)
3.booleanonKeyShortcut(intkeyCode,KeyEventevent)
4.booleanonKeyUp(intkeyCode,KeyEventevent)
5.booleanonTouchEvent(MotionEventevent)
6.booleanonTraceballEvent(MotionEventevent)
基于回调机制的方法都有一个boolean型返回值,true表示事件已经结束,false表示需要继续传播。
Android的事件监听与传统Java略有区别:
1.首先,监听器接口通常以内部类的形式出现,例如View提供了六个监听接口:
View.OnClickListener、View.OnKeyListenerView.OnTouchListener、View.OnCreateContextMenuListsner、View.OnFocusChangeListener、View.OnLongClickListener。
2.其次,Android增加监听接口的方法命名方式为set...Listener,而不是传统Java的add...Listener。
顾名思义,貌似Android不再需要职责链模式来处理事件响应了。
3.第三,Android可以直接编写事件处理方法,而不需要实现新的监听类!
可以直接在界面布局文件中为控件的指定事件设置处理方法名(这个有点儿接近Flash的编程风格了)。
5Activity和Fragment
5.1Activity的生命周期和相关回调方法
Activity是Android的应用主界面,应用需要从继承Activity开始。
Activity的执行由系统来控制,Android系统通过调用Activity的回调方法来调度其运行。
为简化编码工作,Android为很多回调方法提供了缺省实现——这样你就不需要再为不需响应的事件编写空方法了。
因此Android类库中更多地使用了抽象类来替代接口。
Activity有四种稳定状态(尚有一些中间状态):
1.活动状态:
可见并拥有焦点;
2.暂停状态:
可见但丧失了焦点;
3.停止状态:
不可见,当然也没有焦点;
4.销毁状态:
Activity结束,或其所在的Dalvik进程被结束。
下图描述了Activity的状态转换过程,并注明了过程转换时系统回调的Activity方法。
回调方法是开发Activity的重要内容。
5.2Activity的子类和层次结构
Activity的层次结构如下。
图的上半部分描述了Activity的祖先,下半部分(android.app包)列举了Android为适应不同应用的特点而提供的Activity不同风格的子类。
5.3Activity的调用和加载
Activity可以使用startActivity(Intentintent)方法启动其它Activity。
startActivity没有直接使用被启动Activity的名字作为参数,而是采用了灵活性更高的Intent类型参数(见前文Intent类介绍)。
如果启动者希望被启动Activity返回数据,则需要使用startActivityForResult(Intentintent,intrequestCode)方法。
此时需要两个额外的方法:
1.启动者需重写protectedonActivityResult(intrequestCode,intresultCode,Intentintent)方法来接受返回数据,并执行后续处理。
这种方式实现了异步调用。
2.被调用者需要调用setResult(intresultCode)或setResult(intresultCode,Intentintent)方法(final方法)设置处理结果。
前者简单地返回一个整型结果,后者可以附加用户数据。
如果可以调用多个Activity,在运行时不能预知哪个Activity被实际调用,也就不能感知是谁在回调onActivityResult方法了。
requestCode参数就是用来解决这个问题。
requestCode由调用者传给被调用者,再由调用者传回来。
其思路是调用者预先为每个被调用者指定一个id(requestCode),回调时再带回来。
频繁的调用可能导致Activity被多次加载。
由于Android资源相对紧张,其对Activity的加载模式管理比较细腻,包括Standard、SingleTop、SingleTask、SingleInstance四种模式。
后三种均可含有单例模式的意思,SingleTop是当启动任务在栈定时直接复用(不创建新实例),SingleTask是整个任务(Task,本文不探讨其概念)只能由一个实例,SingleInstance是整个系统只能有一个实例。
5.4Fragment
Fragment是Android3.0的新增类。
它类似Java的Panel,可以将某些常用UI控件及其行为组合为一个组件,在不同Activity间重用。
Fragment的生命周期与所在的Activity相同。
Fragment的设计初衷是为了适应大屏幕的平板电脑。
平板电脑可容纳更多UI控件,Fragment可以对这些控件分组,以便于提高开发效率。
FragmentManager负责管理Fragment的交互,Activity.getFragmentManager()方法用于获取所需的FragmentManager。
6图像处理
6.1使用Drawable资源
StateListDrawable用于组织多个Drawable资源。
当作为组件的前景、背景时,可以随组件的状态改变自动切换图片。
LayerDrawable可包含一个Drawable数组。
可以通过控制数组对象的顺序来实现图像的变化,达到不同的动画效果。
ShapeDrawable用于定义一个基本的几何图形。
可以基于它实现绘图。
Bitmap表示一个静态位图,可以与BitmapDrawable互相转换。
BitmapFactory是操作位图的工具类,提供了大量解析创建位图的方法。
ClipDrawable表示一个位图的片段,可通过它实现缩进、展开等动画效果。
AnimationDrawable代表动画,包括传统的帧动画和通过平移、变换计算出来的补间动画。
PropertyAnimation表示属性动画。
它有AnimatorSet、ValueAnimator、TimeAnimator、ObjectAnimator等不同子类,可实现渐变等复杂动画效果。
有关动画的技巧请见后文。
6.2绘图
Android绘图类似于Java,需要重写要绘图的View子类的onDraw方法,并提供了一个绘图类Canvas,类似于Graphics。
Canvas的画笔是Paint类,具有渐变、阴影等眩效果。
Canvas还可以使用Path,把多个点连成“路径”。
类似传统Java,Android也允许通过setBitmap方法把Canvas和Bitmap关联起来。
这样就可以通过预先将图形绘制到Bitmap上,而实现双缓冲效果。
Android还支持通过Matrix类实现图形变幻,通过Canvas.drawBitmapMesh方法扭曲图像,通过Shader填充图形,实现复杂的特效效果。
6.3动画
帧(Frame)动画。
通过为AnimationDrawable对象指定item集(每个item为一帧),再设置其onshot属性为true,即可实现帧动画效果。
补间动画。
补间动画只需指定关键帧即可,中间帧由系统计算补齐。
Android提供了以下几个实现补间动画的子类:
1.AlphaAnimation实现透明度改变动画;
2.ScaleAnimation实现大小缩放动画;
3.TranslateAnimation实现位移动画;
4.RotateAnimation实现旋转动画。
属性动画。
补间动画的“增强”版,几乎可以对任何UI组件实现更复杂的动画效果(四种动画的叠加)。
如果想实现更好的动画效果,可以考虑使用SurfaceView代替View。
SurfaceView支持双缓冲和局部绘制,动画切换效果更平稳。
7数据处理
Android系统中可以使用传统Java的IO包来实现文件读写。
Android也提供了一些专门的IOAPI,使输入输出工作更加有效。
如果处理的数据较多、较复杂,可以使用Android内置的轻量级数据库SQLite。
Android为访问SQLite提供了大量API。
Android还提供了ContentProvider类,作为应用间数据交换的标准API。
应用可以通过ContentProvider暴露自己的数据,其它应用可以使用ContentProvider访问别人暴露的数据。
7.1支持少量数据存取的SharedPreferences
SharedPreferences使用key-values形式保存数据。
SharedPreferences本身是个接口,Context提供了getSharedPreferences(Stringname,intmode)方法来获取SharedPreferences实例。
其中name可以理解为保存数据的文件名,mode包括:
1.Context.MODE_PRIVATED:
数据仅用于本应用自己读写;
2.Context.MODE_WORLD_READONLY:
数据可被其它应用读;
3.Context.MODE_WORLD_WRITEABLE:
数据可被其它应用读写。
SharedPreferences提供了如下数据存取方法(含义不言自明):
1.booleancontains(Stringkey)
2.abstractMap>getAll()
3.xxxgetXxx(Stringkey,xxxdefaultValue)
SharedPreferences的内部接口Editor提供了写入数据的方法,包括:
1.voidclear()
2.voidputXxx(Stringkey,xxxvalue)
3.voidremove(Stringkey)
4.booleancommit()。
Editor需要提交才能使修改生效
SharedPreferences的数据据说在/data//shared_prefs目录下,以xml格式保存。
应用可以读取其它应用的SharedPreferences。
方法是创建其它应用的上下文:
createPackageContext("其它应用的包名",Context.CONTEXT_IGNORE_SECURITY),并通过该Context来获取SharedPreferences实例。
读取使用的包名和文件名都可以在data目录下找到。
7.2读写SD卡的文件
SD卡文件可以使用java.IO包的方法读写。
在读写前,可通过Environment检查是否插入了SD卡,以及SD卡对应的目录。
getExternalStorageState()判断是否安装了SD卡。
该方法返回String类型,需要与Environment.MEDIA_MOUNTED比较才能完成判断。
getExternalStorageDirectory()获取SD卡的安装目录。
7.3使用SQLite数据库
SQLite支持大部分SQL92语法,但是很轻量,每个数据库就是一个文件(有点儿像的dBase、Access),没有数据库进程,需要在应用中打开后才能使用。
SQLit