Activity数据传递之通用方式:
抽象类型 Parcelable
通过静态变量传递数据:容易发生内存泄漏,尽量不要使用
1、Android系统的底层建立在Linux系统之上,该平台由操作系统、中间件、用户界面和应用软件4层组成,它采用一种被称为软件叠层的方式进行构建。
这种分工保证了层与层之间的低耦合,当下层的层内或层下发生改变时,上层应用程序无须任何改变。
2、Android系统主要由5部分组成,下面分别对这5部分进行简单介绍:
(1)应用程序层:
Android系统将会包含系列的核心应用程序,包括电子邮件客户端、SMS程序、日历、地图、浏览器、联系人等。这些应用程序都是用java编写的。
(2)应用程序框架:
当我们开发Android应用程序时,就是面向底层的应用程序框架进行的。从这个意义上看,Android系统上的应用程序时完全平等的,不管是Android 系统提供的 程序,还是普通开发者提供的程序,都可以访问Android提供的API框架。Android应用程序框架提供了大量API供开发者使用。
*:应用程序框架除可作为应用程序开发的基础之外,也是软件复用的重要手段,任何一个应用程序都可发布它的功能模块——只要发布时遵守了框架的约定,那么其他应用程序也可以使用这个功能模块。
(3)函数库:
Android包含一套被不同组件所使用的C/C++库的集合。一般来说,Android应用开发者不能直接调用这套C/C++库集,但可以通过它上面的应用程序框架来调用这些库。
下面列出一些核心库:
#系统C库:一个从BSD系统派生出来的标准C系统库(libc),并且专门为嵌入式Linux设备调整过。
#媒体库:基于PacketVideo的openCORE,这套媒体库支持播放和录制许多流行的音频和视频格式,以及查看静态图片。主要包括MPEG4、H.264、MP3、AAC、AMR、JPG、PNG等多媒体格式。
#Surface Manager:管理对显示子系统的访问,并可以对多个应用程序的2D和3D图层机提供无缝整合。
#LibWebCore:一个全新的Web浏览器引擎,该引擎为Android浏览器提供支持,也为WebView提供支持,WebView完全可以嵌入开发者自己的应用程序中。
#SGL:底层的2D图形引擎。
#3D libraries:基于OpenGL ES 1.0 API实现的3D系统,这套3D库可以使用硬件3D加速(如果硬件系统支持),也可使用高度优化的软件3D加速。
#FreeType:位图和向量字体显示。
#SQLite:供所有应用程序使用的、功能强大的轻量级关系数据库。
(4)Android运行时:
Android运行时由两部分组成:Android核心库集和Dalvik虚拟机。其中核心库集提供了java语言核心库所能使用的绝大部分功能,而虚拟机则负责运行Android应用程序。
每个Android应用程序都运行在单独的Dalvik虚拟机内(即每个Android应用程序对应一条Davlik进程),Dalvik专门针对同时高效地运行多个虚拟机进行了优化,因此Android系统可以方便的实现对应用程序进行隔离。
由于Android应用程序的编程语言是java,因此有些人会把Dalvik虚拟机和JVM搞混,但二者存在区别:Dalvik并未完全遵守JVM规范,两者也不兼容。实际上,JVM虚拟机运行的是JAVA字节码(通常就是.class文件),但Dalvik运行的是其专有的dex(Dalvik Executable)文件。JVM直接从.class文件或JAR包中加载字节码然后运行;而Dalvik则无法直接从.class文件或JAR包中加载字节码,它需要通过DX工具将应用程序的所有.class文件编译成.dex文件,Dalvik则运行该.dex文件。
Dalvik虚拟机非常适合在移动终端上使用,相对于在pc或服务器上运行的虚拟机而言,Dalvik虚拟机不需要很快的cpu计算速度和大量的内存空间,它主要有如下两个特点:
#运行专有的.dex文件。专有的.dex文件减少了.class文件中的冗余信息,而且会把所有.class文件整合到一个文件中,从而提高运行性能,;而且DX工具还会对.dex文件进行一些性能的优化。
#基于寄存器实现。大多数虚拟机(包括JVM)都是基于栈的,而Dalvik虚拟机则是基于寄存器的。一般来说,基于寄存器的虚拟机具有更好的性能表现,但在硬件通用性上略差。
Dalvik虚拟机依赖于Linux内核提供的核心功能,如线程和底层内存管理。
(5)Linux内核:
安全性、内存管理、进程管理、网络协议栈和驱动模型等核心系统服务。除此之外,Linux内核也是系统硬件和软件叠层之间的抽象层。
3、Activity:
Activity是Android应用中负责与用户交互的组件,只能通过setContentView(View)来显示指定组件。
实际上Activity是Window的容器,Activity包含一个getWindow()方法,该方法返回该Activity所包含的窗口,对于Activity而言,开发者一般不需要关心Window对象。
多个Activity组成Activity栈,当前活动的Activity位于栈顶。
或者使用Activity将它显示出来。
LinearLayout对象是ViewGroup的子类,ViewGroup又是View的子类
Activity包含了一个setTheme(int resid)方法来设置其窗口的风格,我们若希望窗口不显示ActionBar、以对话框形式显示窗口,都可通过该方法来实现。
Service:
Service与Activity的地位是并列的,它也代表一个单独的Activity组件。Service与Activity的区别在于:Service通常位于后台运行,它一般不需要与用户交互,因此Service组件没有图形用户界面。
提供后台服务或监控其他组件的运行状态。
BroadcastReceiver:
从代码实现角度来看,BroadcastReceiver非常类似于事件编程中的监听器。与普通事件监听器不同的是:普通事件监听器监听的事件源是程序中的对象;而BroadcastReceiver监听的事件源是Android应用中的其他组件。
系统级的“事件监听器”:
#在java代码中通过Context.registReceiver()方法注册BroadcastReceiver。
#在AndroidManifest.xml文件中使用<receiver.../>元素完成注册。
ContentProvider:
对于Android应用而言,他们必须相互独立,各自运行在自己的dalvik虚拟机实例中,如果这些Androidying'yong之间需要实现实时的数据交换,Android系统为这种跨应用的数据交换提供了一个标准:ContentProvider。
通常与ContentProvider结合使用的是contentResolver,一个应用程序使用ContentProvider暴露自己的数据,而另一个应用程序则通过ContentResolver来访问数据。
4、Intent 和 IntentFilter
Intent不是Android应用的组件,是Android应用内不同组件之间通信的载体。也即是说,Activity、Service、BroadcastReceiver三种组件之间的通信都以Intent作为载体。
目标组件的信息。
可分为两类:
#显式Intent:明确指定需要启动或者触发的组件的类名。
Android系统无须对该Intent进行解析,系统直接找到指定的目标组件,启动或触发它即可。
#隐式Intent:只是指定需要启动或者触发的组件应满足怎样的条件。
Android系统需要对该Intent进行解析,解析出它的条件,然后再去系统中查找与之匹配的目标组件。如果找到符合条件的组件,就启动或触发它们。
IntentFilter来声明自己所满足的条件——也就是声明自己到底能处理哪些隐式Intent。
5、Android应用的绝大部分UI组件都放在android.widget包及其子包、android.view包及其子包中,android应用的所有UI组件都继承了View类。
Drawable是Android提供的一个抽象基类,它代表了“可以被绘制出来的某种东西”,Drawable包括了大量子类,比如BitmapDrawable代表位图Drawable、ColorDrawable代表颜色Drawable、ShareDrawable代表几何形状Drawable。各种Drawable可用于定制UI组件的背景等外观。
ViewGroup容器控制其子组件的分布依赖于ViewGroup.LayoutParams、ViewGroup.MarginLayoutParams两个内部类。这两个内部类中都提供了一些XML属性,ViewGroup容器中的子组件可以指定这些XML属性。
6、#Android推荐使用XML布局文件来控制视图,这样不仅简单、明了,而且可以将应用的视图控制逻辑从java代码中分离出来,放入XML文件中控制,从而更好地体现MVC原则。
#如果希望在代码中控制UI界面,那么所有的UI组件都将通过new关键字创建出来,然后程序使用LinearLayout容器来“盛装”这些UI组件,这样就组成了图形用户界面。
但这种方式不仅编程繁琐,而且不利于高层次的解耦,因此不推荐开发者使用这种方式。
public class CodeView extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState)
// 创建一个线性布局管理器
LinearLayout layout = new LinearLayout(this);
// 设置该Activity显示layout
super.setContentView(layout);
layout.setOrientation(Linearlayout.VERTICAL);
// 创建一个TextView
final TextView show = new TextView(this);
// 创建一个按钮
Button bn = new Button(this);
bn.setText(R.string.ok);
bn.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
// 向Layout容器中添加TextView
layout.addView(show);
// 向Layout容器中添加按钮
layout.addView(bn);
// 为按钮绑定一个事件监听器
bn.setOnClickListener(new OnClickListener()
{
@Override
public void OnClick(View v)
{
show.setText("Hello, Android, "
+ new java.util.Date());
}
});
}
}
让UI组件持有一个Context参数,可让这些UI组件通过该Context参数来获取Android应用环境的全局信息。
Context本身是一个抽象类,Android的应用的Android、Service都继承了Context,因此Activity、Service都可直接作为Context使用。
#当混合使用XML布局文件和代码来控制UI界面时,习惯上把变化小、行为比较固定的组件放在XML布局文件中管理,而那些变化较多、行为比较复杂的组件则交给java代码来管理。
7、开发自定义View:
View组件只是一个矩形的空白区域,View组件没有任何内容。对于Android应用的其他UI组件来说,它们都继承了View组件,然后在View组件提供的空白区域上绘制外观。
当开发者打算派生自己的UI组件时,首先定义一个继承View基类的子类,然后重写View类的一个或多个方法,通常可以被用户重写的方法如下。
#构造器:重写构造器是定制View的最基本方式,当java代码创建一个View实例,或根据XML布局文件加载并构建界面时将需要调用该构造器。
#onFinishInflate(): 这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被回调。
#onMeasure(int, int): 调用该方法来检测View组件及它所包含的所有子组件的大小。
#onLayout(boolean, int, int, int): 当该组件需要分配其子组件的位置、大小时,该方法就会被回调。
#onSizeChanged(int, int, int, int): 当该组件的大小被改变时回调该方法。
#onDraw(Canvas): 当该组件将要绘制它的内容时回调该方法进行绘制。
#onKeyDown(int, KeyEvent): 当某个键被按下时触发该方法。
#onKeyUp(int, KeyEvent): 当松开某个键时触发该方法。
#onTrackballEvent(MotionEvent): 当发生轨迹球事件时触发该方法。
#onTouchEvent(MotionEvent): 当发生触摸屏事件时触发该方法。
#onWindowFocusChanged(boolean): 当该组件得到、失去焦点时触发该方法。
#onAttachedToWindow(): 当把该组件放入某个窗口时触发该方法。
#onDetachedFromWindow(): 当把该组件从某个窗口上分离时触发该方法。
#onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发该方法。