android应用开发 - 沈大海
DESCRIPTION
Android应用开发 - 沈大海TRANSCRIPT
LAMP 人 主题分享交流会
wwwLAMPERcnQQ 群 3330312
httpweibocomlampercn
Android 开发技术培训
沈大海
知识大纲bull Android 手机空间划分bull Android Frameworkbull Android SDKNDK 开发环境搭建bull Android Application 分析bull Android Loop Handler 机制bull Android 应用开发基本组件使用bull 实现 AIDL 定义远程通讯 Servicebull 实现 WidgetWallpaperbull Google Map 开发bull LocaltionManagerbull 使用 NDK 开发bull 开源引擎 Cocos2d-x 介绍bull 开发优化
Android 手机软硬件形态
Android Framework5
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 开发技术培训
沈大海
知识大纲bull Android 手机空间划分bull Android Frameworkbull Android SDKNDK 开发环境搭建bull Android Application 分析bull Android Loop Handler 机制bull Android 应用开发基本组件使用bull 实现 AIDL 定义远程通讯 Servicebull 实现 WidgetWallpaperbull Google Map 开发bull LocaltionManagerbull 使用 NDK 开发bull 开源引擎 Cocos2d-x 介绍bull 开发优化
Android 手机软硬件形态
Android Framework5
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
知识大纲bull Android 手机空间划分bull Android Frameworkbull Android SDKNDK 开发环境搭建bull Android Application 分析bull Android Loop Handler 机制bull Android 应用开发基本组件使用bull 实现 AIDL 定义远程通讯 Servicebull 实现 WidgetWallpaperbull Google Map 开发bull LocaltionManagerbull 使用 NDK 开发bull 开源引擎 Cocos2d-x 介绍bull 开发优化
Android 手机软硬件形态
Android Framework5
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 手机软硬件形态
Android Framework5
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android Framework5
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 体系结构bull 应用程序 (Applications) 依据 User 的期望而将 AF 的组件及
Libaraies 组件组合而成的高阶服务bull 应用框架 (Application Framework 简称 AF) 这是结合
Applications与 Libraries 的幕后主架构让 Libraries 组件能不断地为 Applications 所重复使用 (Reuse)
bull 丰富而又可扩展的视图( Views )bull 内容提供器( Content Providers )bull 资源管理器( Resource Manager )bull 通知管理器 ( Notification Manager )bull 活动管理器( Activity Manager )
bull Libraries Android 里已经提供的 CC++ 库存组件 ( 或称模块 ) 例如 SQLite 数据库系统 OpenGL 3D 绘图系统等
bull Android Runtime Java 语言层级的 Virtual Machine bull Linux 核心 Android 依赖 Linux 26 来提供核心的服务例如内存
管理进程 (Process) 管理执行绪 (Thread) 管理等
6
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android层次 -kernel
Android基于 Linux 26提供核心系统服务例如安全内存管理进程管理网络堆栈驱动模型 Linux Kernel也作为硬件和软件之间的抽象层它隐藏具体硬件细节而为上层提供统一的服务
使用 binder作为进程间通讯机制取代传统进程间通讯机制
7
Linux KernelLinux KernelDisplay Driver
Camera Driver
Flash Driver
SD Driver
Keypad Driver
Touch Driver
USB Driver
PM
Common Kernel(File System
Networking etc)
HardwareHardwareCamera
ISPTouchCPU
MVED Driver
GCU Driver
MM Accelerate
BatteryCharging
RTC Alarm
Modem
IPC Driver
WIFIBT
Android Enhancement(Binder Ash
Log ADB etc) Sensors Driver
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android ndash Hardware Abstraction Layer
用户空间的 CC++库遵循 Apache协议定义 Android需要 linux driver实现的接口将 Android彻底和硬件抽象出来
8
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android层次结构 -Android Runtime
Android包含一个核心库的集合提供大部分在 Java编程语言核心类库中可用的功能Dalvik虚拟机则是基于寄存器的而非大多数 虚拟机所采用的基于栈的实现Dalvik虚拟机依赖于 Linux 内核提供基本功能 如线程和底层内存管理
9
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android包含一个 CC++库的集合供 Android系统的各个组件使用这些功能通过 Android的应用程序框架( application framework)暴露给开发者下面列出一些核心库系统 C库多媒体库 OpenCore界面管理LibWebCoreSGL3D库FreeTypeSQLite
Android层次结构 -Libraries10
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android层次结构- Application Framework
通过提供开放的开发平台 Android使开发者能够编制极其丰富和新颖的应用程序开发者可以自由地利用设备硬件优势访问位置信息运行后台服务设置闹钟向状态栏添加通知等等很多很多开发者可以完全使用核心应用程序所使用的框架 APIs应用程序的体系结构旨在简化组件的重用任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功
能(需要服从框架执行的安全限制)这一机制允许用户替换组件 所有的应用程序其实是一组服务和系统包括ViewActivityManagerContentProviderNotificationManager
11
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android层次结构- Applications
Android魅力的终极体现 对用户良好的用户体验强大的用户亲和力 对开发者快速而灵活的开发平台让开发者的灵感能快速转化为产品
12
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 进程运行
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
基本开发方向 -Android 移植集成所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroid python 使用Androidbuildtools
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
基本开发方向 - 应用开发
所需知识
Android 核心组件Android UI 组件Android GUI 编程Android 事件处理NDK 开发OpenGL 开发
编译工具EclipseJava C 语言
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
基本开发方向mdash Android 系统开发所需知识 Linux 操作系统知识 Linux 内核知识 Linux 驱动程序知识 Android 底层库Dalvik 虚拟机 Android GUI 系统音频视频和多媒体 电话部分的连接部分传感器部分
编译工具Vim 或者 EmacsAndroid Shell 脚本Android makefileAndroidbuildtoolsJava 开发JNI 技术
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
三种开发形式bull SDK 开发
ndash Windows linux mac
bull NDK 开发ndash Windows linux
bull 源码开发ndash (完全源代码 Linux 中开发)
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android Applications
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android apk build and packaging
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android application unpackaging and run
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
AAPT 打包示意图21
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
限定符的类型和有效的值 限定符 有效值语言 语言码遵循 ISO 639-1 标准小写如 en zh
地区 遵循 ISO 3166-1-alpha-2 标准大写前面加小写的ldquo rrdquo 例如 rUS rCN
屏幕朝向 port land square
屏幕像素密度 92dpi 108dpi 等触摸屏类型 notouch stylus finger
键盘是否可用 keysexposed keyshidden
首选的输入法 nokeys qwerty 12key
首选非触摸导航方法 nonav dpad trackball wheel
屏幕尺寸 320x240 640x480 等大尺寸必须在前
22
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
资源管理框架23
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Activity 介绍
l展现为一个用户可视化界面lActivity可以多种形式呈现如全屏模式对话框模式透明模式等lActivity的部分重要属性
l androidlabel=string resource l androidicon=drawable resource l androidlaunchMode=[multiple | singleTop |singleTask | singleInstance]
24
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
基础 UI
bull menu 如何打造友好的菜单bull ListView 用好列表做好程序bull Dialog 人机友好互动交流bull Toast和 Notification 温馨的提醒bull 各种 View 组件bull 自定义 View 组件
25
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Application ui description
通过绑定 Activity的 setContentView() 方法在 onResume 之后绘制
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
A tree-structure ui
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Viewwindows base
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
图形系统层次结构
Android Apps
Application Framework
Native Libraries
HAL
SurfaceFlinger
Activity Manager Window ManagerView System
Display Driver(FrameBuffer)
View ---- Image Shape Text Animation Canvas
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
2D graphics processActivity
androidviewandroidgraphics(Canvas PaintPathPictureRegion)
ActivityManagerWindowManager
frameworksbasecorejniandroidgraphic
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
externalskia
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
3D graphics processActivity
androidopengljavaxmicroeditionkhronosegljavaxmicroeditionkhronosopengl(GLSurfaceView)
ActivityManagerWindowManager
frameworksgles_jni
SurfaceFlinger
HAL FrameBuffer
Get Surface Obj
frameworksbaseopengl
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 图形系统 GUI includeJava --- androidgraphics (Skia lib draw feature) androidviewsurface androidviewview javaxmicroeditionkhronosopengles androidopenglCC++ --PixelFlinger (tool lib) libui SurfaceFlinger Skia Opengles 3D
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 图形系统
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画tween
对 view 的内容进行一系列变换 ( 平移 缩放 渐变 )
frame
顺序播放一组图片 达到动画的效果
动画的类型 Xml 定义动画使用的配置节点 编码定义动画使用的类
渐变透明度动画效果 ltalphagt AlphaAnimation
渐变尺寸缩放动画效果 ltscalegt ScaleAnimation
画面位置移动动画效果 lttranslategt TranslateAnimation
画面旋转动画效果 ltrotategt RotateAnimation
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 ( 缩放 )定义动画文件 resanimscalexml
ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltscale
androidinterpolator=androidanimaccelerate_decelerate
_interpolator
androidfromXScale=00 起始时 X 轴比例 ( 相较于图片本身 )
androidfromYScale=00
androidtoXScale=5 结束时 y 轴上的比例androidtoYScale=5
androidpivotX=50 x 轴轴心androidpivotY=50 y 轴轴心androidfillAfter=false 为 true 该动画转化在动画结束后被应用androidduration=5000gt 持续时间 (毫秒 )
ltsetgt
注 LinearInterpolatorAccelerateinterpolatorDecelerateInterpolator
自定义
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 ( 缩放 )定义布局文件ltImageView
androidlayout_width=wrap_content
androidlayout_height=wrap_content
androidsrc=drawableicon
androidid=+idimageViewgt
加载动画 XML 文件 生成动画指令Animation animation = AnimationUtilsloadAnimation(this Ranimscale)
开始执行动画imageViewstartAnimation(animation)
编程式ScaleAnimation animation = new ScaleAnimation(00f 5f 00f 5f
AnimationRELATIVE_TO_SELF 05f
AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 ( 透明 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltalpha
androidfromAlpha=01
androidtoAlpha=10
androidduration=3000gt
ltsetgt
AlphaAnimation animation = new AlphaAnimation(01 10)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 ( 移动 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
lttranslate
androidrepeatCount=2
androidfromXDelta=0
androidfromYDelta=0
androidtoXDelta=120
androidtoYDelta=120
androidduration=3000gt
ltsetgt
TranslateAnimation animation = new TranslateAnimation(0 120 0 120)
animationsetDuration(5000) 设置持续时间 5秒imageViewstartAnimation(animation)
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 ( 旋转 )ltxml version=10 encoding=utf-8gt
ltset xmlnsandroid=httpschemasandroidcomapkresandroidgt
ltrotate
androidinterpolator=androidanimaccelerate_interpolator
androidrepeatCount=2
androidfromDegrees=0
androidtoDegrees=+360
androidpivotX=50
androidpivotY=50
androidduration=3000gt
ltsetgt
RotateAnimation animation = new RotateAnimation(0 -90 AnimationRELATIVE_TO_SELF 05f AnimationRELATIVE_TO_SELF 05f)
animationsetDuration(500)
imageViewstartAnimation(animation)
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 动画 (frame)准备图片 resdrawable1gif 2gif
resaniframexml
ltxml version=10 encoding=utf-8gt
ltanimation-list
xmlnsandroid=httpschemasandroidcomapkresandroid
androidoneshot=falsegt
ltitem androiddrawable=drawablegirl_1 androidduration=200 gt
ltitem androiddrawable=drawablegirl_3 androidduration=200 gt
ltanimation-listgt
imageViewsetBackgroundResource(Ranimframe)
animationDrawable = (AnimationDrawable) imageViewgetBackground()
public boolean onTouchEvent(MotionEvent event)
if (eventgetAction() == MotionEventACTION_DOWN) 按下animationDrawablestart()
return true
return superonTouchEvent(event)
注
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
事件处理ndash onKeyDownndash onTouchEvent
bull Activityndash onResume 后
bull Viewndash设为焦点
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 手势识别添加视图监听器
gestureOverlayViewaddOnGesturePerformedListener()
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
mLibraryload()
gestureOverlayView = thisfindViewById(Ridgestures)
gestureOverlayViewaddOnGesturePerformedListener(GestureListener())
mLibrary = GestureLibrariesfromRawResource(this Rrawgestures)
state = mLibraryload() 加载手势库
interface GestureOverlayViewOnGesturePerformedListener
public void onGesturePerformed(GestureOverlayView oGesture g)
ListltPredictiongt=mLibraryrecognize(gesture)
Prediction prediction = predictionsget(0)
predictionscore0-100
predictionname名称
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 传感器传感器类型方向传感器 SensorTYPE_ORIENTATION
加速度 ( 重力 ) 传感器 SensorTYPE_ACCELEROMETER
光线传感器 SensorTYPE_LIGHT
磁场传感器 SensorTYPE_MAGNETIC_FIELD
距离 (临近性 ) 传感器 SensorTYPE_PROXIMITY
温度传感器 SensorTYPE_TEMPERATURE
获取传感器Sensor sensor =
sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
注册监听 获取传感器变化值sensorManagerregisterListener(listener sensor
SensorManagerSENSOR_DELAY_GAME)
注
上面第三个参数为采样率 最快 游戏 普通 用户界面 当应用程序请求特定的采样率时 其实只是对传感器子系统的一个建议 不保证特定的采样率可用
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 传感器 获取感应器管理器sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE)
accelerometer = (TextView) findViewById(Ridaccelerometer)
orientation = (TextView) findViewById(Ridorientation)
protected void onResume()
获取重力加速度传感器Sensor sensor = sensorManagergetDefaultSensor(SensorTYPE_ACCELEROMETER)
sensorManagerregisterListener(listener sensor SensorManagerSENSOR_DELAY_GAME)
获取方向传感器Sensor sensor1 = sensorManagergetDefaultSensor(SensorTYPE_ORIENTATION)
sensorManagerregisterListener(listener sensor1SensorManagerSENSOR_DELAY_GAME)
superonResume()
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 传感器注册监听器private SensorEventListener listener = new SensorEventListener()
public void onSensorChanged(SensorEvent event) float x = eventvalues[SensorManagerDATA_X]
float y = eventvalues[SensorManagerDATA_Y]
float z = eventvalues[SensorManagerDATA_Z]
switch (eventsensorgetType())
case SensorTYPE_ACCELEROMETER
break
case SensorTYPE_ORIENTATION
break
public void onAccuracyChanged(Sensor sensor int accuracy)
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android Application
bull Application就是 Activity Service 之类的组件上下文描述
bull Activity Broadcast Intent Receiver 服务( Service )内容提供器( Content Provider )这些组件依附于应用程序中
bull 应用程序并不会一开始就建立起来而是在这些组件建立起来后需要运行时才开始建立应用程序对象
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Activity 所绑定的进程名称bull androidname=string bull androidprocess=string bull Activity Manager Service 在应用程序的第一个组件需要运
行时将会为应用程序建立一个进程而这个进程的名字就是 androidprocess=rdquostringrdquo 所指定缺省的是应用程序包的名字
bull 在建立 Actvitiy 时如果在应用进程端没有应用对象系统在该过程中利用 makeApplication 建立一个 Application对象实例化 androidappApplication 建立一个应用程序上下文完成例如资源 package 等信息管理
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
进程与生命周期bull Android 系统会尽可能长的延续一个应用程序进程但在内存过低的时候仍然会不可避免需要移除旧的进程为决定保留或移除一个进程 Android 将每个
进程都放入一个ldquo重要性层次rdquo中依据则是它其中运行着的组件及其状态重要性最低的进程首先被消灭然后是较低的依此类推重要性共分五层依据重要性列表如下
bull 1 前台进程bull 是用户操作所必须的当满足如下任一条件时进程被认为是处于前台的 bull 任一时间下仅有少数进程会处于前台仅当内存实在无法供给它们维持同时运行时才会被杀死一般来说在这种情况下设备已然处于使用虚拟内存的
状态必须要杀死一些前台进程以用户界面保持响应bull 2 可视进程bull 没有前台组件但仍可被用户在屏幕上所见当满足如下任一条件时进程被认为是可视的bull o 它包含着一个不在前台但仍然为用户可见的 activity (它的 onPause() 方法被调用)这种情况可能出现在以下情况比如说前台 activity
是一个对话框而之前的 activity 位于其下并可以看到 bull o 它包含了一个绑定至一个可视的 activity 的服务bull 可视进程依然被视为是很重要的非到不杀死它们便无法维持前台进程运行时才会被杀死bull 3 服务进程bull 是由 startService() 方法启动的服务它不会变成上述两类尽管服务进程不会直接为用户所见但它们一般都在做着用户所关心的事情(比如在后台播放
mp3 或者从网上下载东西)所以系统会尽量维持它们的运行除非系统内存不足以维持前台进程和可视进程的运行需要bull 4 背景进程bull 包含目前不为用户所见的 activity( Activity对象的 onStop() 方法已被调用)这些进程与用户体验没有直接的联系可以在任意时间被杀死以回收内存供
前台进程可视进程以及服务进程使用一般来说会有很多背景进程运行所以它们一般存放于一个 LRU (最后使用)列表中以确保最后被用户使用的activity最后被杀死如果一个 activity正确的实现了生命周期方法并捕获了正确的状态则杀死它的进程对用户体验不会有任何不良影响
bull 5 空进程bull 不包含任何活动应用程序组件这种进程存在的唯一原因是做为缓存以改善组件再次于其中运行时的启动时间系统经常会杀死这种进程以保持进程缓存和
系统内核缓存之间的平衡bull Android 会依据进程中当前活跃组件的重要程度来尽可能高的估量一个进程的级别比如说如果一个进程中同时有一个服务和一个可视的 activity 则进程
会被判定为可视进程而不是服务进程bull 此外一个进程的级别可能会由于其它进程依赖于它而升高一个为其它进程提供服务的进程级别永远高于使用它服务的进程比如说如果 A 进程中的内
容提供者为进程 B 中的客户端提供服务或进程 A 中的服务为进程 B 中的组件所绑定则 A 进程最低也会被视为与进程 B拥有同样的重要性
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
ActivityThreadbull 应用进程不是 Application 而是 ActivityThread 从实际的应用堆栈可以看到
bull NaiveStartmain()bull ZygoteInitmainbull ZygoteInit$MethodAndArgsCallrunbull MethodInvokebull methodinvokeNativebull ActivityThreadmain()bull Looperloop()
bull 每个应用程序都以 ActivityThreadmain()为入口进入到消息循环处理 bull 应用程序通过 ActivityThread 提供的框架建立消息循环 Looper和 Handlerbull ActivityThread 建立与 Activity Manager Service (简称 AMS )的通讯接口
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
默认的线程为主线程主线程负责 UI 及事件处理每个线程中都有一个 Looper 循环处理本线程的消息队列线程之间通过消息通讯主线程中也可以创建辅助线程但辅助线程不能直接操作 UI 可以线程中创建 Looper 通过消息进行
进程中的线程
APK PackageProcess
ThreadLooper
Message Queue
ThreadExternal Service
Calls
IntentReceiver
Activity
Activity
UI Events
System Events
Local Service
Call
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android消息系统 Loop Handler bull Android消息系统使用了 LooperMessageQueueHandler 等概念 Handler 先进先出原则 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange)
ndash Looper 一个线程可以产生一个 Looper对象由它来管理此线程里的 Message Queue(消息队列 ) Looper只是产生一个消息循环框架首先 Looper创建了消息队列并把它挂接在Linux 的线程上下文中进入到取消息并分发消息的循环当中
ndash Handler Handler对象在同一个线程上下文中取得消息队列对消息队列进行封装操作最主要的就是 SendMessage 和担当起 dispatchMessage 这个实际工作外部系统需要向某个Android线程发送消息必须通过属于该 AndroidThread的 Handler 这个对象进行
ndash Message Queue(消息队列 ) 用来存放线程放入的消息ndash 线程 UI thread 通常就是 main thread 而 Android启动程序时会替它建立一个Message
Queue
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Activity的四个状态
1 ActiveRuning 一个新 Activity 启动入栈后它在屏幕最前端处于栈的最顶端此时它处于可见并可和用户交互的激活状态2 Paused 当 Activity 被另一个透明或者 Dialog 样式的Activity 覆盖时的状态此时它依然与窗口管理器保持连接系统继续维护其内部状态所以它仍然可见但它已经失去了焦点故不可与用户交互3 Stoped 当 Activity 被另外一个 Activity
覆盖失去焦点并不可见时处于 Stoped状态4 Killed Activity 被系统杀死回收或者没有被启动时处于Killed状态
53
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Activity 的各个回调函数与状态 之间的关系
l protected void onCreate(Bundle savedInstanceState) l protected void onStart() l protected void onResume() l protected void onPause() l protected void onStop() l protected void onDestroy()
54
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull在 Android中 应用的响应性被bull活动管理器 (Activity Manager)和bull窗口管理器 (Window Managerndash(这两个系统服务所监视 ndash当用户触发了输入事件 (如键盘输入 点击按钮等 ) ndash如果应用 5秒内没有响应用户的输入事件 那么 Android会认ndash为该应用无响应 便弹出 ANR(Application No Response)
ndash在正常情况下 Android程序会在一条单线程里运行 如果 Activity要处理一件比较耗时的工作 应ndash该交给子线程完成 否侧会因为主线程被阻塞 后面的用户输入事件因没能在 5秒内响应 导致应用出现
Android- 应用程序的响应性
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Intent56
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
57
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
58
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
59
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
60
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Intent 跟 pendingIntent 间的联系
bull intent 执行后的操作常和 alermanger 和notificationmanager 一起使用 Intent 一般是用作Activity Sercvice BroadcastReceiver之间传递数据而 Pendingintent 一般用在 Notification上可以理解为延迟执行的intent
bull PendingIntent 是对 Intent 一个包装
61
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
BroadcastReceiver简介lBroadcastReceiver的作用每个 Broadcast Receiver都可以接收一种或若干种 Intent作为触发事件
lBroadcastReceiver不执行任何任务仅仅是接受并响应广播通知的一类组件
lBroadcastReceiver 不包含任何用户界面
62
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Service 简 介
是什么Service在 Android中是一种长生命周期的组件它不实现任何用户界面用来做什么实现不需要用户界面但是需要一直运行的功能如音乐播放器怎么用实现一个自己的 service启动执行 contextstartService()contextbindService()
63
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Service 的生命周期
64
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-与服务进行进程间通信客户端和服务通过 IBinder对象联系在一起 bindService() 方法调用时 需要 IntentServiceConnection和 flag参数 其中 serviceConnection对象用于接收服务 onBind() 方
法返回的 IBinder对象 并且该对象会传入到第二个参数 serviceConnetion对应的方法中 触发
方法的回调 总而言之 使得客户端持有到达 service对象的引用
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-AIDL 实现进程间通信对于客户端和服务之间通信 虽然可以通过 IBinder 实现 但需要共享业务实现 如果在进程间通信的话 需要使用 AIDL(Android Interface Definition Language) 进行
AIDL 是一种接口定义语言 用于约束两个进程间的通讯规则 供编译器生成代码 实现 Android设备上的两个进程间通信 (IPC)AIDL的 IPC 机制和 EJB 所采用的 CORBA很类似 进程之间的通信信息 首先会被转换成 AIDL协议消息 然后发送给对方 对方收到 AIDL协议消息后再转换成相应的对象 由于进程之间的通信信息需要双向转换 所以 android采用代理类在背后实现了信息的双向转换 代理类由 android 编译器生成 对开发人员来说是透明的
使用方式如下 1 定义 AIDL(同接口相似 但没有可见性 扩展名有 java--gt aidl)IDownloadServiceaidl 注意扩展名package cnshenaidlinterface IDownloadService
void download(inoutinout String path)in|out|inout 是参数的方向 ide 会自动在 gen 包下生成对应的 java类 接口文件中生成一个 Stub 的抽象类 里面包括 aidl 定
义的方法 还包括一些其它辅助方法 值得关注的是 asInterface(IBinder iBinder)它返回接口类型的实例 对于远程服务调用 远程服务返回给客户端的对象为代理对象 客户端
onServiceConnected(ComponentName name IBinder service) 方法引用该对象时不能直接强转成接口类型的实例 而应该使用 asInterface(IBinder iBinder) 进行类型转换
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-AIDL 实现进程间通信编写 AIDL 需要注意 1 接口名和 aidl 文件名相同 2 接口和方法前不用加访问权限修饰符 publicprivateprotected等 也不能用 finalstatic3Aidl默认支持的类型包话 java 基本类型 (intlongboolean等 )和 (StringListMap CharSequence) 使用这些类型时不需要 import声明 对于 List和 Map 中的元素类型必须是 Aidl支持的类型 如果使用自定义类型作为参数或返回值 自定义类型必须实现 Parcelable 接 口 4自定义类型和 AIDL生成的其它接口类型在 aidl描述文件中 应该显式 import即便在该类
和定义的包在同一个包中 5在 aidl 文件中所有非 Java 基本类型参数必须加上 in out inout 标记 以指明参数是
输入参数输出参数还是输入输出参数 6Java原始类型默认的标记为 in 不能为其它标记
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-AIDL 实现进程间通信javabean 必须实现 Parcelable 接口class Person implements Parcelable
idnamegetsetpublic int describeContents()
return 0把 javanbean 中的数据写到 Parcelpublic void writeToParcel(Parcel dest int flags) destwriteInt(thisid)
destwriteString(thisname)添加一个静态成员 名为 CREATOR该对象实现了 ParcelableCreator 接口public static final ParcelableCreatorltPersongt CREATOR = new ParcelableCreatorltPersongt()
public Person createFromParcel(Parcel source) return new Person(sourcereadInt() sourcereadString())public Person[] newArray(int size) return new Person[size]
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-AIDL 实现进程间通信在自定义类型包中定义 aidl 声明文件Personaidl注意 parcelable 是小写package cnshendomainparcelable Person
接口定义文件需要显式导入自定义类型 ( 即时在同一个包下 )PersonServiceaidlpackage cnshenaidlimport cnshendomainPersoninterface IPersonService void save(in Person person)
创建 aidl 接口实现类 ( 通过继承 $ 业务接口 stub 类实现 )public class ServiceBinder extends IPersonServiceStub
public void save(Person person) throws RemoteException Logi(PersonService persongetId()+=+ persongetName())
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-AIDL 实现进程间通信实现 service的 onBind 方法 返回值就是上一步创建的 aidl 实现类对象 public IBinder onBind(Intent intent)
return new ServiceBinder()
客户端通过隐式意图访问服务 ltservice androidname=PersonServicegt
ltintent-filtergtltaction androidname=cnshenprocessaidlPersonService gt
new Intent(cnshenprocessaidlPersonService)
复制 aidl 文件和所在包到客户端对应的 src下 ( 客户端会自动生成对应 java类 )thisbindService(thisscBIND_AUTO_CREATE)sc = new ServiceConnection()
public void onServiceConnected(ComponentNameIBinder service) personService = IPersonServiceStubasInterface(service)personServicesave(new Person(56liming))
public void onServiceDisconnected(ComponentName name)
personService = null
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
IPC 框架分析 bull Android 的设计 Activity托管在不同的的进
程 Service也都是托管在不同的进程不同进程间的 ActivityService 之间要交换数据属于 IPC
bull Binder就是为了 Activity 通讯而设计的一个轻量级的 IPC 框架
bull Binder 是一个很低层的概念上面一层根本都看不到 Binder 而是 Activity跟一个 Service 的对象直接通过方法调用获取服务
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
IPC-对象请求代理架构bull 在 Android 中要完成某个操作所需要做
的就是请求某个有能力的服务对象去完成动作而无需知道这个通讯是怎样工作的以及服务在哪里
bull Andoid的 IPC 在本质上属于对象请求代理架构 Android 的设计者用 CORBA 的概念将自己包装了一下实现了一个微型的轻量级 CORBA 架构
bull 只是解决本机的进程间的通讯
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 的对象代理结构
Service Manager
提供了
add service
check service
两个重要的方法并且维护了一个服务列表记录登记的服务名称和句柄
这样 client 应用能够找到所需要的 service
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Binder architecture Binder java Binder c++
Java binder framework
Native binderframework
Binder core systemBBinder-gtIBinderlt-BpBinder
Binder AdapterIPCThreadeStateProcessState
Binder linux driver
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Binder 核心类bull IBinder
ndash 虚拟类bull BBinder
ndash BBinder有 onTransact消息处理函数 bull BpBinder
ndash BpBinder 有消息传递函数 transcat
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Service 闭合循环框架
bull Android 设计中 Native Service和 Android Service 采用了同一个闭合循环框架这个闭合循环框架放置在 Native的 C++ 空间中 ProcessStateProcessStatecpp 和 IPCThreadStateIPCThreadStatecpp
两个类完成了全部工作 bull 关于 ProcessState和 IPCThreadState在系统开发课程介绍
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android 启动过程bull (1) init 进程启动bull (2) Native 服务启动bull (3) System Server Android 服务启动bull (4) Home 启动
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull 文件操作bull Preferences10556401055640bull SQLite 库存储bull 网络
bull content provider
Android 中的数据保存78
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
文件操作
bull openFileInputbull openFileOutput
bull 读取资源文件bull getResource()openRawResource(Rrawxxx)
79
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Preferences
bull 轻量级的bull 保存的是原始数据类型bull 常用于保存程序配置信息
SharedPreferences settings = getSharedPreferences(SETTING_INFOS 0)String name = settingsgetString(NAME )String password = settingsgetString(PASSWORD )
80
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull 过 ContextgetSharedPreferences()得到一个bull SharedPreferences bull 获取一个 Editor 对保存的参数进行编辑bull commit() 进行提交bull SharedPreferences settings = getSharedPreferences(ldquoinfordquo 0)bull Editor editor = settingsedit()bull editorputString(ldquonamerdquo nameEditTextgetText()toString())bull putString(ldquopwdrdquo passwordEditTextgetText()toString())bull commit()
81
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 使用嵌入式 SQLite
Android 平台上集成的一个嵌入式关系型数据库 SQLite3支持 NULLINTEGERREAL (浮点数字) TEXT(字符串文本 ) 和 BLOB(二进制对象 ) 数据类型 虽然它支持的类型只有五种 但实际上 sqlite3也接受 varchar(n)char(n)decimal(ps) 等数据类型 只不过在运算或保存时会转成对应的五种数据类型
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中 而不用关心字段声明的数据类型是什么 但定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数 当向这种字段保存除整数以外
的数据时 将会产生错误 另外 SQLite 在解析 CREATE TABLE 语句时 会忽略字段名后面的数据类型信息
SQLite 可以解析大部分标准 SQL 语句 如 查询语句 select from where group by having
order by 排序子句SQLite 分页同 mysql 相同 limit 5 offset 3 | limit 35
82
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 使用嵌入式 SQLite
首次使用数据库需要创建表及初始化一些信息 升级时需要修改表信 android 提供了抽象类 SQLiteOpenHelper 完成此类功能
onCreate(SQLiteDatabase db) 方法用于首次使用时创建库 onUpgrade(SQLiteDatabase db int oldVersion int
ewVersion) 方法检测版本发生变化时更新库 getWritableDatabase()和 getReadableDatabase() 方法均获取一个用于操作数据库的 SQLiteDatabase 实例
getWritableDatabase() 方法以读写方式打开数据库 一旦数据库的磁盘空间满了 数据库就只能读而不能写 倘若使用getWritableDatabase() 打开数据库就会出错 getReadableDatabase() 方法先以读写方式打开数据库 如果数据库的磁盘空间满了 就会打开失败 当打开失败后会继续尝试以只读方式打开数据库
83
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-单元测试ltapplication androidicon=drawableicon package=gt ltuses-library androidname=androidtestrunner gt ltapplicationgtltinstrumentation androidname=androidtestInstrumentationTestRunner
androidtargetPackage=cnshenaction androidlabel=Tests for My App gt
public class XMLTest extends AndroidTestCase public void testSomething() throws Throwable
Logi(Test this is test 日志 )Systemoutprintln(ddd)AssertassertTrue(1 + 1 == 3)
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-SQLite3 工具使用
ltTableLayout xmlnsandroid=httpschemasandroidcomapkresandroid
androidlayout_width=fill_parent androidlayout_height=wrap_content androidstretchColumns=0123 androidid=+idtlListgtltTableLayoutgt
85
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
ContentProvider简介lContentProvider是 Android提供的一种标准的共享数据的机制 l应用程序可以通过 content provider访问其它应用程序的一些私有数据lContentProvider的优点屏蔽了内部数据的存储细节向外提供l了上述统一的接口模型
86
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 使用 ContentProvider
使用内容供应商共享数据 如果直接访问磁盘文件 (SDCard|File|SQLite 数据库 | 首选项 ) 需要很多
底层的交互细节 但是用该种方式 只使用 url即可对应用程序进行访问 并统一了数据访问方式 public class PersonContentProvider extends
ContentProviderpublic boolean onCreate()public Uri insert(Uri uri ContentValues values)
ltapplication androidicon=drawableicon
androidlabel=stringapp_namegtlt-- 注册供应商 --gtltprovider androidname=PersonContentProvider
androidauthorities=cnlgproviderspersonprovidergtltapplicationgt
87
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 使用 ContentProvider
88
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-活动墙纸活动墙纸是 android21新增的特性 活动墙纸实质上是一个包含有 WallpaperService的 android应用 该服务必须含有一个 WallpaperServiceEngine该 Engine 是用户 surface 和系统之间的桥梁 他拥有绘制墙纸的 surface
首要的是 WallpaperService 必须携带内部 Engine 类进行创建 而且需要使用androidservicewallpaperWallpaperService 意图声明在清单文件中 以备设备识别为活动墙纸 需要关联 androidpermissionBIND_WALLPAPER权限到活动墙纸给 android 主程序
ltserviceandroidname=LiveWallpaperServiceandroidenabled=trueandroidicon=drawableiconandroidlabel=stringapp_nameandroidpermission=androidpermissionBIND_WALLPAPERgtltintent-filter androidpriority=1 gtltaction androidname=androidservicewallpaperWallpaperService gtltintent-filtergtltmeta-dataandroidname=androidservicewallpaperandroidresource=xmlwallpaper gt
ltservicegt
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-活动墙纸墙纸描述文件
添加文件 resxmlwallpaperxml描述活动墙纸 ltmeta-data androidname=androidservicewallpaper
androidresource=xmlwallpaper gt
ltxml version=10 encoding=UTF-8gtltwallpaper xmlnsandroid=httpschemasandroidcomapkresandroid
androidthumbnail=drawablethumbnailandroiddescription=stringdescriptionandroidsettingsActivity=PreferenceActivitygt
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-活动墙纸创建墙纸服务类public class LiveWallpaperService extends WallpaperService
public Engine onCreateEngine() return new SampleEngine()
public class SampleEngine extends Engine public void onCreate(SurfaceHolder surfaceHolder)public void onVisibilityChanged(boolean visible)public void onSurfaceChanged()public void onSurfaceCreated(SurfaceHolder holder)
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Widgetbull ltreceiver androidname=MeWidgetProvider
androidicon=drawableboot_robotandroidlabel=AppWidget Lifegt
bull ltintent-filtergtbull ltaction
androidname=androidappwidgetactionAPPWIDGET_UPDATEgtbull ltactiongtbull ltcategory
androidname=androidintentcategoryDEFAULTgtltcategorygtbull ltintent-filtergtbull ltmeta-data androidresource=xmlapp_widget_infobull androidname=androidappwidgetprovidergtbull ltmeta-datagtbull ltreceivergt
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
获取手机所有连接管理对象bull public static boolean checkNet(Context context)
bull 获取手机所有连接管理对象(包括对 wi-finet 等连接的管理) bull try
bull ConnectivityManager connectivity = (ConnectivityManager) context
bull getSystemService(ContextCONNECTIVITY_SERVICE)
bull if (connectivity = null)
bull 获取网络连接管理的对象 bull NetworkInfo info = connectivitygetActiveNetworkInfo()
bull if (info = nullampamp infoisConnected())
bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED)
bull return true
bull
bull catch (Exception e)
bull
bull return false
bull
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
检查网络状态变化bull ltreceiver androidname=itcastutilNetCheckgt bull ltintent-filtergt bull ltaction androidname=androidnetconnCONNECTIVITY_CHANGEgt bull ltintent-filtergt bull ltreceivergtbull public class NetUtil extends BroadcastReceiverbull public void onReceive( Context context Intent intent ) bull bull ConnectivityManager connectivityManager = (ConnectivityManager)
contextgetSystemService( ContextCONNECTIVITY_SERVICE ) bull NetworkInfo info = connectivityManagergetActiveNetworkInfo() bull if (info = nullampamp infoisConnected()) bull 判断当前网络是否已经连接 bull if (infogetState() == NetworkInfoStateCONNECTED) bull ToastmakeText( context ok ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull elsebull bull ToastmakeText( context err ToastLENGTH_SHORT )show() bull bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongtbull ltuses-permission androidname=androidpermissionACCESS_NETWORK_STATEgt
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
AsyncTaskbull 匿名线程的方式是存在缺陷的bull 第一线程的开销较大如果每个任务都要创建一个线程那么应用
程序的效率要低很多bull 第二线程无法管理匿名线程创建并启动后就不受程序的控制了
如果有很多个请求发送那么就会启动非常多的线程系统将不堪重负另外前面已经看到在新线程中更新 UI还必须要引入 handler 这让代码看上去非常臃肿
bull bull 为了解决这一问题 Android在 15版本引入了 AsyncTask bull AsyncTask 的特点是任务在主线程之外运行而回调方法是在主线程
中执行这就有效地避免了使用 Handler带来的麻烦阅读AsyncTask 的源码可知 AsyncTask 是使用 javautilconcurrent 框架来管理线程以及任务的执行的 concurrent 框架是一个非常成熟高效的框架经过了严格的测试这说明 AsyncTask 的设计很好的解决了匿名线程存在的问题
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
AsyncTask 是抽象类bull doInBackground(Params p) 在此方法中实现任务的执行工作比如连接网络获取数据等通常还应该实现
bull onPostExecute(Result r) 方法因为应用程序关心的结果在此方法中返回需要注意的是AsyncTask 一定要在主线程中创建实例
ndash AsyncTask 定义了三种泛型类型 Params Progress和 Result
bull Params 启动任务执行的输入参数比如 HTTP请求的 URL
bull Progress 后台任务执行的百分比 bull Result 后台执行任务最终返回的结果比如 String
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
ndash onPreExecute() bull 当任务执行之前开始调用此方法可以在这里显示进度对话框
ndash doInBackground(Params)bull 此方法在后台线程执行完成任务的主要工作通常需要较长的时间在执行过程中可以调用publicProgress(Progress) 来更新任务的进度
ndash onProgressUpdate(Progress)bull 此方法在主线程执行用于显示任务执行的进度
ndash onPostExecute(Result) bull 此方法在主线程执行任务执行的结果作为此方法的参数返回
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android-互联网 ( 多线程下载 )
1 多线程下载取得下载文件大小 并构建随机访问文件HttpURLConnectiongetContentLength()RandomAccessFile file = new RandomAccessFile(QQWubiSetupexerwd)filesetLength(filesize)设置本地文件的长度设置每个线程连接的请求属性 range为指定范围HttpURLConnectionsetRequestProperty(Range bytes=2097152-4194303) 定位文件位置写入信息 fileseek(2097152)filewrite()
注 多线程下载时 不要判断 200值 style=androidstyleWidgetProgressBarHorizontalltstyle name=WidgetProgressBarHorizontalgt ltitem name=androidindeterminateDrawablegt
androiddrawableprogress_indeterminate_horizontalltitemgt ltitem name=androidminHeightgt20dipltitemgt ltitem name=androidmaxHeightgt20dipltitemgtltstylegt动态添加进度条时 指定的是 androidRattrprogressBarStyleHorizontal样式值
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
ListView 优化bull public class WeiboStatuAdapter extends BaseAdapter
bull public Context con
bull public ListltStatusgt alls
bull public LayoutInflater lif
bull public WeiboStatuAdapter(Context conListltStatusgt as)
bull thiscon=con
bull lif=LayoutInflaterfrom(con)
bull thisalls=as
bull
bull public int getCount() return allssize()+2
bull public Object getItem(int arg0) return null
bull public long getItemId(int index)
bull if(index==0) 选中第一项bull return 0
bull else if(indexgt0ampamp(indexltthisgetCount()-1))
bull return allsget(index-1)getId() 如果用户选中了中间项 bull else
bull return -1 表示用户选中最后一项bull
bull 增加更多的数据bull public void addMoreData(ListltStatusgt moreStatus)
bull thisallsaddAll(moreStatus) 把新数据增加到原有集合bull thisnotifyDataSetChanged()
bull
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 多媒体 (照相机 )
thisrequestWindowFeature(WindowFEATURE_NO_TITLE)无标题Window w = thisgetWindow()wsetFlags(WindowManagerLayoutParamsFLAG_FULLSCREEN
WindowManagerLayoutParamsFLAG_FULLSCREEN)设置全屏waddFlags(WindowManagerLayoutParamsFLAG_KEEP_SCREEN_ON) 高亮
surfaceViewgetHolder()setFixedSize(176 144)设置分辨率surfaceViewgetHolder()setType(SurfaceHolderSURFACE_TYPE_PUSH_BUFFERS)surfaceViewgetHolder()addCallback()回调
WindowManager wm = getSystemService(ContextWINDOW_SERVICE)窗口管理器Display display = wmgetDefaultDisplay()Camera camera = Cameraopen() 打开照相机CameraParameters parameters = cameragetParameters()parameterssetPreviewSize(displaygetWidth()displaygetHeight()) 大小parameterssetPreviewFrameRate(3)每秒 3帧parameterssetPictureFormat(PixelFormatJPEG)设置照片的输出格式parametersset(jpeg-quality 85)照片质量parameterssetPictureSize(displaygetWidth()displaygetHeight())camerasetParameters(parameters)
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 多媒体 (照相机 )
通过 SurfaceView显示取景画面camerasetPreviewDisplay(surfaceViewgetHolder())camerastartPreview() 开始预览cameraautoFocus(null)自动对焦cameratakePicture(null null null jpegCallback)拍照片camerastopPreview()停止预览camerarelease()释放摄像头
onKeyDownpublic boolean onKeyDown(int keyCode KeyEvent event)
if(camera = null ampamp eventgetRepeatCount() == 0)case KeyEventKEYCODE_SEARCH
PictureCallbackBitmap bmp = BitmapFactorydecodeByteArray(data 0 datalength)File jpg = new File(EnvironmentgetExternalStorageDirectory()1jpg)FileOutputStream fos = new FileOutputStream(jpg)bmpcompress(BitmapCompressFormatJPEG 100fos)fosclose()camerastartPreview()
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android- 多媒体 (照相机 )
使用意图模拟拍照若没有摄像头硬件 可使用系统内置的 provider 实现摄像头功能 (该功能 22 的模拟器不支持 )
Intent intent = new Intent(androidproviderMediaStoreACTION_IMAGE_CAPTURE) 指定输出文件outputFileUri指定照片存放的地址 若有的话存放全尺寸大照片 否则返回位图 在 onActivityResult 方法中接收intentputExtra(MediaStoreEXTRA_OUTPUT outputFileUri)startActivityForResult(intent 0)
BitmapFactoryOptions options = new BitmapFactoryOptions()optionsinSampleSize = 1Bitmap bitmap = BitmapFactorydecodeFile(_path options)_imagesetImageBitmap(bitmap)lt-- 需要使用如下权限 --gtltuses-permission androidname=androidpermissionCAMERA gt ltuses-feature androidname=androidhardwarecamera gt ltuses-feature androidname=androidhardwarecameraautofocus gt
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull Button btaddPic=(Button)thisfindViewById(RidbtGallery)bull btaddPicsetOnClickListener(new OnClickListener()bull bull Overridebull public void onClick(View v) bull Intent i = new
Intent(androidmediaactionIMAGE_CAPTURE)bull startActivityForResult(i ActivityDEFAULT_KEYS_DIALER)bull bull bull )
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull protected void onActivityResult(int requestCode int resultCode Intent data)
bull TODO Auto-generated method stubbull superonActivityResult(requestCode resultCode data)bull Bundle extras = datagetExtras()bull Bitmap b = (Bitmap) extrasget(data)bull ByteArrayOutputStream baos = new ByteArrayOutputStream()bull bcompress(BitmapCompressFormatJPEG 100 baos)bull dat = baostoByteArray()bull thishasPic=true
bull
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
地图开发bull Google 地图
ndash Google MAPndash 位置导航
bull 第三方地图ndash 高德
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull 1获取指纹bull CDocuments and SettingsAdministratorgtcd C
Documents and SettingsAdministratbull orandroid
bull CDocuments and SettingsAdministratorandroidgtkeytool -list -keystore debugkEystore
bull 默认密码 androidbull 2申请 apikeybull httpcodegooglecomintlzh-CNandroidmaps-api-si
gnuphtml
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
使用 Google 地图bull MapActivity
bull 任何显示 MapView的 Activity都要继承这个类bull 内部封装了访问网络的方法
bull MapView
bull MapControllerbull 控制地图的 移动和缩放
bull Overlay
bull GeoPoint
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull ltuses-library androidname=ldquocomgoogleandroidmapsrdquogt
bull ltuses-permission androidname=androidpermissionINTERNETgtltuses-permissiongt
bull MapView map=new MapView(thisrdquokeyrdquo)
bull MapsetTraffic 地图模式bull Map setSatellite卫星模式bull MapsetStreetView街景模式
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull MapControl=mMapviewgetController()
bull geoPoint=new 成都GeoPoint((int)30659251000000 (int)1040657621000000)
bull mMapControlleranimateTo(geoPoint)
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull Public class myLocationOverLay extends OverLay
bull
bull public boolean draw(Canvas cmapView mboolean shadwlong when)
bull
bull
bull
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
定位系统bull LocationManager
bull getSystemService(ConextLOCATION_SERVICE)bull 注册周期更新视图的侦听bull LmrequestLocationUpdates(LocationmanagerGPS_PROVI
DER10000LocationListener)
bull LocationProviderbull LocationListener
bull onLocationChangedbull onProviderDisabledbull onproviderEnabledbull onStatusChanged
bull Criteriabull GeoCoder
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull ( 1 ) public void setAccuracy( int accuracy ) bull 位置解析的精度高或低参数 Criteria ACCURACY_FINE 精确模式 Criteria ACCURACY_COARSE 模糊模式
bull ( 2 ) public void setAltitudeRequired(boolean altitudeRequired ) bull 是否提供海拔高度信息是或否 bull ( 3 ) public void setBearingRequired( boolean bearingRequired ) bull 是否提供方向信息是或否 bull ( 4 ) public void setCostAllowed( boolean costAllowed ) bull 是否允许运营商计费是或否bull ( 5 ) public void setPowerRequirement( int level ) bull 电池消耗无低中高参数 Criteria NO_REQUIREMENT
Criteria POWER_LOW Criteria POWER_MEDIUM or Criteria POWER_HIGH
bull ( 6 ) public void setSpeedRequired( boolean speedRequired )
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull criteriasetAccuracy(ACCURACY_FINE)
bull ACCURACY_FINE
bull 精确度设置为模糊解决所有手机无法启动CriteriaACCURACY_COARSE
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
Android Ndk 开发bull JNI 实现 NDK 定义的 native 方法调用bull 1 编写 Java 类定义 native 方法bull 2 通过 javah命令生成类的 h 文件bull 3创建 c 的项目工程bull 4 编写 c 的函数实现bull 5 编译生成 sobull 6拷贝 so到 java项目中bull 7在 staticbull SystemloadLaibrary(xxxx)bull bull 8直接调用 native 方法
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
应用程序的优化bull 代码优化的关键
o 少用浮点运算文件 pipe 数据库访问o 用高效的方式 StringBuffer 代替大量临时 String o SoundPool 代替多个 MediaPlayer o texture 代替 canvas o Logd() 代替 Systemoutprint() o 避免 invalidate()o 重视 onMeasureonLayoutonDrawonTouchEventgetView 等函
数的效率bull 游戏开发
o 少用 new()enumIteratorHashMapArrayssort()ClassgetXXX()hellip
o 多用 private final 局部变量o 2D 善用 draw_texture 3D 善用 VBO 顶点缓冲o 触屏事件时暂停接受运动感应事件o 用 NDK 实现关键代码
bull 不要求速度时可用 WebView 和网页实现界面bull 编译时执行代码优化
bull 谢谢
bull 谢谢