android框架及应用开发介绍 信息应用开发部 2009年9月
目录 Android的发展 初探Android框架 如何开发一个android应用 如何开发一个widget 2
Android发展路线 ?android 2.0,代号donut,支持CDMA,多点触摸,文本语音引擎,… 2008年9月23日,HTC G1上市,android SDK 1.0发布 2008年10月21日,android开源 2009年4月27日,android SDK 1.5发布 ?android 2.0,代号donut,支持CDMA,多点触摸,文本语音引擎,… Sdk1.5,开放了appwidget的api
Android手机一览 华为pulse Htc tattoo,低端手机 LG Etna
目录 Android的发展 初探Android框架 如何开发一个android应用 如何开发一个widget 5
Android框架 JNI JAVA C/汇编 Android框架分为四层:kernel、libraries、framework、applications 1. 最低层是linux kernel,主要负责内存管理、进程调度等系统管理以及终端的硬件驱动。Binder driver,google为android设计的一个增强系统的进程间通信能力的模块。 2. Kernel的上一层是libraries,包含了核心库、第三方库和android虚拟机。android并没有直接采用传统的j2se或j2me的java虚拟机,而是自己建立了一个称为dalvik的虚拟机,号称更节省字节码的空间,性能更好。但这也成为了google与sun关于java版权争议点。 以上两层是采用C语言或汇编语言实现的。 3. Framework是android为应用开发者设计的一套软件框架,提供了丰富的api和一些现成的开发元素。Framework是采用java语言实现的。在NDK出来之前,android应用开发者基本上只能用java来开发应用。 Android使用JNI连接了libraries和framework。 4. Application就是在framework的基础上开发的各种应用。 以上是android系统的总体框架。
Android应用程序构成 Activity Service Intent Broadcast Receiver Content Provider 下面具体看看一个android应用程序的框架。 包含了5个部分:activity,service,intent,broadcast receiver,content provider
Activity
Activity A visual user interface 通过view管理UI 每一个有用户界面的应用至少包含一个activity 一个应用可以有多个activity,其中一个作为main activity用于启动显示 Activity通过startActivity或startActivityForResult启动另外的activity
Activity——View 通过View管理UI View绘制UI与处理UI event View可通过xml描述定义,也可在代码中生成。 setContentView(R.layout.main) Android建议将UI设计和逻辑分离 android UI设计类似swing,通过布局(layout)组织UI组件 在android中,生成用户界面的方式: 通过xml描述文件的方式 直接在代码中生成 两者结合
Activity生命周期 Activity通过onCreate被创建 当一个activity失去焦点,该activity将进入pause状态,系统在内存不足时会将其终止 当一个activity被另一个activity覆盖,该activity将进入stop状态,系统在需要内存的时候会将其终止 当activity处于pause或者stop状态时,都可能被系统终止并回收。因此,有必要在onPause和onStop方法中将应用程序运行过程中的一些状态,例如用户输入等,保存到持久存储中。如果程序中启动了其他后台线程,也需要注意在这些方法中进行一些处理,例如在线程中打开了一个进度条对话框,如果不在pause或stop中cancel掉线程,则当线程运行完cancel掉对话框时就会抛出异常。 Project:ActivityLifecycle
Intent
Intent(1) 类似于消息、事件通知 Intent构成:action、category、data Activity、Service、broadcast receiver之间的桥梁 activity service Intent Intent可以理解为应用程序向系统表达的一种意愿:希望系统做什么。 一个Activity可以通过intent来启动另外的activity或service实例,或者通过intent来发起一个广播。 Service可以通过intent来启动一个activity或另一个service实例,也可以通过intent发起一个广播。 Broadcast receiver通过获取intent取得其关注的广播消息。 Broadcast receiver
Intent(2) 两类intent: 显式:指定具体的目标组件处理 startActivity(new Intent(ActivityLifecycle.this, AnotherActivity.class)); 隐式:由系统接受并决定如何处理 startActivity(new Intent(Intent.ACTION_DIAL)); 在AndroidManifest.xml中定义activity、service、broadcast receiver接受的intent 显式的,应用程序向系统发出intent,指明需要哪一个component处理。 隐式的,应用程序向系统发出一个intent,但没有具体指明该intent的接收者,由系统匹配最合适的接收者负责处理。如果存在多个匹配,那么系统会弹出对话框给用户选择处理的应用。 系统如何知道哪些component可以处理哪些intent?在androidmanifest.xml文件中定义intent-filter
Intent(3) Intent filter: action、category、data Component name Action activity Filter分三类,action、category、data 在filter中定义相关的匹配规则,告知系统对应的component可以接受哪些intent service framework component Broadcast receiver intent
实例 action -- DIAL data -- tel:02038639592 action -- VIEW Project:HelloIntent
Service
Service 没有UI,启动之后一直运行于后台 例子:音乐播放器 与应用程序的其他模块(例如activity)一同运行于主线程中 通过startService或bindService创建Service 通过stopService或stopSelf终止Service 一般的,在activity中启动和终止service
Service生命周期 onCreate onStart onDestroy Context.startService() Context.bindService() Context.stopService() Serivce.stopSelf() 一个service也有其生命周期,从创建到启动,到最后的撤销。 上一页ppt提到两种创建service的方法,startService或者bindService,他们的区别就在于,startService是创建并启动service,而bindService只是创建了一个service实例并取得了一个与该service关联的binder对象,但没有启动它。 Project: local service controller
Content Provider
何为Content provider 什么是Content provider? 为何需要content provider? Content Provider 是Android应用程序的四大组成部分之一 是android中的跨应用访问数据机制 为何需要content provider? Android中每一个app的资源是私有的 app通过content provider和其他app共享私有数据 在android中,系统对资源和数据的管理机制是这样的: 每一个应用的资源是私有的,如果应用本身没有开放这些资源,其他应用是无法访问到这些资源的。Android通过将每一个应用视为一个linux用户来实现这一机制。 那么,如果一个应用希望它所拥有的资源和数据可以被其他应用使用,那么就需要通过content provider来对外提供访问接口。
如何使用content provider 通过content resolver访问 Context.getContentResolver() app app app ContentResolver ContentResolver ContentResolver ContentProvider A ContentProvider B 如何使用content provider? Android使用了content resolver和uri数据表示方式,提供对content provider的统一访问。 应用在使用content resolver访问需要的数据时,系统content resolver根据传入的uri,定位到该uri对应的content provider,完成相应的操作。 Content provider提供了一种类似于数据库二维表的数据展现和访问方式。 从图中也可以看到,一个content provider被注册之后,它就可以被所有的应用通过content resolver访问了。
如何使用content provider(续) URI定位资源 content://contacts/people content://call_log 类似关系数据库的访问方式 以二维数据表的格式暴露数据,缺省都包含_id字段 delete(Uri url, String where, String[] selectionArgs) insert(Uri url, ContentValues values) query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) update(Uri uri, ContentValues values, String where, String[] selectionArgs) Content resolver如何定位具体要访问哪个content provider呢? Android使用uri来定位资源,即content resolver依靠uri来找到要访问的content provider。 两个例子:通信录联系人的uri,第二个是通话记录的uri。 Android提供了一种类似数据库访问的方式来使用content resolver,并且以二维表的形式表现访问的数据。
定义自己的content provider 在AndroidManifest.xml中声明一个provider <provider …>…</provider> 创建MyProvider类,继承自ContentProvider。定义该provider提供的数据集的URI和字段名 在MyProvider中实现ContentProvider的6个abstract method:query, insert, update, delete, getType, onCreate 在其他app中使用ContentResolver通过URI访问MyProvider提供的数据
Android的存储 一般的,应用程序的数据(包括文件)都是私有的 四种持久存储方式 Preferences——类似properties,xml文件 Files Database——SQLite Network
Broadcast Receiver
Broadcast receiver 接收和处理android的广播消息 Android的广播机制 系统事件——例如变换时区、电量低等 应用程序发出广播消息:sendBroadCast 广播消息:intent android Send broadcast Broadcast receiver app
创建Broadcast Receiver 实现一个BroadcastReceiver 注册BroadcastReceiver public class MyAndroidReceiver extends BroadcastReceiver override onReceive(Context context, Intents Intents) 注册BroadcastReceiver 在AndroidManifest.xml文件当中进行注册 在代码当中直接进行注册 <receiver Android:name=“MyAndroidReceiver"> <Intents-filter> <action Android:name=”com.eoeAndroid.action.NEW_BROADCAST”/> </Intents-filter> </receiver> IntentsFilter filter = new IntentsFilter(NEW_BROADCAST ); MyAndroidReceiver MyAndroidReceiver = new MyAndroidReceiver(); registerReceiver(MyAndroidReceiver , filter);
Broadcast receiver生命周期 Create Object onReceive Destroy object Broadcast receiver对象在onReceive返回后被销毁 onReceive中不适合处理异步过程。例如弹出对话框与用户交互,可使用消息栏替代。 Android在接收到一个广播intent之后,找到了处理该intent的broadcast receiver,创建一个对象来处理intent。 然后,调用被创建的broadcast receiver对象的onReceive方法进行处理,然后就撤销这个对象。 需要注意的是,对象在onReceive方法返回之后就被撤销,所以在onReceive方法中不宜处理异步的过程。
Android权限控制 在AndroidManifest.xml中描述一个app的权限 例如: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-persission android:name=“android.permission.INTENET” /> </manifest> 权限举例(参考android. Manifest.permission) 权限名称 权限描述 接收短信 android.permission.RECEIVE_SMS 拨打电话 android.permission.CALL_PHONE 系统启动完毕通知 android.permission.RECEIVE_BOOT_COMPLETED 读取联系人信息 android.permission.READ_CONTACTS 修改联系人信息 android.permission.WRITE_CONTACTS 有时候我们的应用需要使用一些系统提供的能力,例如拨打电话,接收短信等。这时我们就需要向系统申请使用这些能力的权限了。 android通过在androidmanifest文件中申明一系列的<uses-permission>来向应用程序开放指定的权限。
目录 Android的发展 初探Android框架 如何开发一个android应用 如何开发一个widget 31
工欲善其事,必先利其器 Android SDK IDE: eclipse + ADT 最新版本:android-sdk-1.5_r2 AVD: android virtual device ADB: Android Debug Bridge Hierarchyviewer: UI解析 …… IDE: eclipse + ADT ADT: Android Development Tools
Android带UI应用的入口,类似main Hello World Android带UI应用的入口,类似main UI界面设计的xml文件,android中采用一个xml描述UI
Android project Activity class 自动生成的资源定义类 存放应用使用的资源 UI布局描述文件 应用使用的静态字符串 应用程序描述文件
基本UI组件
实例:MyPhonebook
实例:短信未知号码提示
目录 Android的发展 初探Android框架 如何开发一个android应用 如何开发一个widget 38
AppWidget Provider Info App Widget描述文件。定义widget大小、更新频率、接收的intent等 AppWidget Provider Info App widget主体,java类,负责widget初始化,各种消息的响应等 App widget AppWidget Provider App widget界面描述文件。描述widget主界面的布局、包含的控件、显示效果等 AppWidget View 用于配置app widget的activity Configure Activity
App widget的UI设计 纵向屏幕 横向屏幕 Cells Pixels 4 x 1 320 x 100 3 x 3 240 x 300
几个widget
android widget的局限 功能 android管理widget的策略: 界面类是RemoteViews而不是View或ViewGroup 只支持少数布局和控件 布局:LinearLayout, FrameLayout, RelativeLayout 控件:button, TextView, ImageView, ImageButton, ProgressBar, AnalogClock, Chronometer(类似timer) android管理widget的策略: 只有当一个widget的所有实例都被delete了,该widget才会被disable。否则,被delete的widget实例仍然会在后台运行,只是界面没显示。 界面是一个RemoteViews而不是View或者ViewGroup RemoteViews一个硬伤——不支持findViewById,也就是说,无法像在activity中那样,自如的访问各种UI组件。
谢谢!