安卓003高速入门

笔记

一、Android概述

1.1 系统概述

1.1.1  3G

Ø 什么是3G

   英文全称3rd-generation。第三代移动通信技术。是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统。

 

  * 3G制式:

(欧洲版) WCDMA\HSDPA 中国联通採用

(北美版) CDMA 2000\EV-DO 中国电信採用

(中国版)TD-SCDMA\TD-HSDPA:中国移动採用

* 3G的发展:

 1G:仅仅能进行语音通话、模拟信号

2G:包含(GSM\GPRS\EDGE)添加了接收数据的功能,如接收电子邮件或网页

3G:02年国外已经产生。03年开发出中国的3G,09才上市。

在传输声音和数据的速度上有非常大提升

4G.:是第四代移动通信及其技术的简称,是集快速无线网络与有线网络WLAN于一体的通讯网络可以传输高质量视频、图像和数据,传输速率可高达200MPS以上,眼下主流技术有 FDD-LTE、TDD-LTEWIMAX

* 移动通信上网速度变化

 GSM(9K)-->GPRS(42K)-->EDGE(147K)-->WCDMA(2M)-->HSDPA(7.2M)-->FDD-LTE长期演进(200M)

Ø 移动互联网

   IT界三大热点:云计算、物联网、移动互联网

     & 云计算

    云计算是一种通过Internet以服务的方式提供动态可伸缩的虚拟化的资源的计算模式 ,这样的模式提供可用的、便捷的、按需的网络訪问, 进入可配置的计算资源共享池(资源包含网络。server。存储,应用软件。服务),这些资源可以被高速提供,仅仅需投入非常少的管理工作。或与服务供应商进行非常少的交互。

  

& 物联网

   物联网就是物物相连的互联网。

Internet of ThingsIOT),也称为Web of Things

物联网的定义是通过射频识别(RFID)、红外感应器、全球定位系统、激光扫描器等信息传感设备,按约定的协议。把不论什么物品与互联网相连接。进行信息交换和通信。以实现对物品的智能化识别、定位、跟踪、监控和管理的一种网络

& 移动互联网

  移动互联网就是将移动通信互联网二者结合起来,成为一体。也是发展最快、市场潜力最大、前景最诱人的业务,比方:移动社交、移动广告、手机游戏、手机电视、移动商务、移动支付、位置服务、移动电子阅读等

      * 移动智能操作系统

         眼下的智能操作系统有Android 4.4IOS7Windows Phone 8SymbianRIM BlackBerryJ2ME等。市场占有率高的有Android平台、IOS平台和Windows Phone平台,形成三足鼎立的局面

         

 

 

1.1.2  Android历史与发展

Ø Android发展历程

* Android发展大事件

2005Google收购 Android Inc. 開始研究Dalvik VM 虚拟机

2007年 开发手机联盟成立。SDK1.0预览版公布

2008年底 第一款Android手机G1诞生 ,Android  通过Apache License开源

* Android版本号进化历程

  1.X 版本号:入门级别。仅仅适用于手机

  2.X 版本号: 趋于成熟的版本号。仅仅适用于手机

  3.X 版本号:趋于成熟的版本号,仅仅适用于平板

  4.X 版本号:趋于成熟的版本号,对平板和手机进行了整合

  5.X 版本号:  支持64cpu、默认採用ART执行模式等

Android 1.5 Cupcake(纸杯蛋糕、API Level 3)

Android 1.6 Donut(甜甜圈API Level 4)

Android 2.0/2.0.1/2.1 Eclair(松饼API Level 567)

Android 2.2/2.2.1 Froyo(冻酸奶API Level 89)

Android 2.3 Gingerbread(姜饼API Level 10)

Android 3.0/3.1/3.2 Honeycomb(蜂巢  API Level 111213)

Android 4.0/4.0.3 Ice Cream Sandwich(冰激凌三明治API Level 1415)

Android 4.1/4.2/4.3 Jelly Bean(果冻豆  API Level 161718)

Android 4.4 KitKat (奇巧巧克力API Level 19)

Android 5.0 代号L  (API Level  20)    

Ø Android应用场景

  手机、平板、智能电视(机顶盒)、穿戴设备(眼镜、手表)、其他智能嵌入设备

1.1.3  Android体系结构

Ø Android体系结构

 

1. Linux内核层

Android是基于Linux内核的操作系统,在Linux内核层,主要实现安全管理、进程管理、内存管理、电源管理、硬件驱动管理

2. 硬件抽象层

硬件抽象层是对Linux 硬件驱动程序的封装,向上提供接口,屏蔽低层的实现细节。硬件抽象层不开源,可保护硬件厂商的商业秘密。可是会影响系统的性能。

Android对硬件的支持分成了两层,一层放在用户空间(User Space)。一层放在内核空间(Kernel Space),硬件抽象层执行在 用户空间, Linux 内核驱动程序执行在内核空间,内核驱动层仅仅提供简单的訪问 硬件逻辑,详细的实现细节,都放在硬件抽象层中 ,从而维护了硬件厂商的商业利益。

3. 原生库与Android执行时

Android的原生库主要基于C\C++实现的一些原生组件。包含CBionic、浏览器引擎Webkit、多媒体引擎OpenCORESQL数据库SQLite3D渲染引擎OpenGL ES、位图和字体矢量渲染引擎FreeType2D图像渲染引擎SGLSkia Graphics Library)、互联网安全协议SSL等。

Android执行时主要包含Java核心库、Dalvik虚拟机,两者一起构成了Android的应用环境基础

4. 应用框架层

    应用框架层是Google公布的核心应用所使用的API框架。开发者能够使用这些框架提供的API来高速开发自己的应用程序,它本身也是用Java语言实现和开发的。

   Activity Manager(活动管理)Window Manager(窗体管理)View Manager(视图管理)Notification Manager(通知管理)Content Provider(内容提供者)Package Manager(包管理)Resource Manager(资源管理)Location Manager(位置管理)

5. 应用层

应用层是基于Android平台开发的应用,採用Java作为开发语言。包含系统自带的应用(短信管理、联系人管理、图库浏览、网页浏览等)和第三方开发的应用

Ø JVMDVM

* 共同点:

  解释运行 byte code字节码文件

  在操作系统的进程执行一个VM,并执行一个单独的程序

* 不同点:

  程序结构不同:JVM字节码由多个.class文件组成,Davlik 仅仅包括一个 .dex 格式的文件,这个文件包括了程序中全部的类。

  架构不同:Dalvikregister-based基于寄存器。Sun JDK stack-based基于栈。

* Dalvik优势

  编译时提前优化代码而不是等到执行时 。

  虚拟机非常小,占空间小。

能够满足可高效执行多种虚拟机实例。

  常量池改动为仅仅使用32位的索引。以简化解释器。 

* DVM运行过程

  1. 编译为class文件

2. 使用dx工具抽取class文件共性形成.dex

3. 维护内部常量池

 

 

* ART执行模式

    ART模式是Android runtime的简称。在Android4.4版本号后出现,通过在安装应用程序时,自己主动对程序进行代码预读取编译,让程序直接编译成机器语言,而且把它保存起来,免去了Dalvik模式要时时转换代码,实现高效率、省电、手机执行流畅。ART是虚拟机。仅仅是在安装app时,提前编译而已。

 

1.2 搭建开发环境

1.2.1  开发环境搭建

* 开发工具

  JDKEclipseADT(Android developer tools)插件、Android SDK

* 工具下载

  ADT下载地址:http://dl.google.com/android/ADT-22.0.0.zip

SDK下载地址:http://dl.google.com/android/android-sdk_r22-windows.zip

合集版下载地址: developer.android.com

   合集版工具包包括:

Eclipse + ADT plugin  

Android SDK Tools    

Android Platform-tools 

The latest Android platform

The latest Android system image for the emulator

      * Android-SDK更新

  通过Android Manager.exe 工具更新

  Android SDK文件夹介绍

   

1.2.2  创建AVD模拟器

* 创建模拟器

 

* 小细节

       & AVD配置文件位置(默认)

C:\Documents andSettings\Administrator\.android\avd\AVD2.3.3.avd\config.ini

       & AVD 缩放 :启动模拟器—>launch Option中选择 Scale display to real size

  & 模拟器不能保存数据:在模拟器的配置文件里删除.lock文件

1.2.3 手机參数

     * 手机屏幕參数:屏幕尺寸、分辨率、屏幕密度

       &手机尺寸:5.5 5.04.74.34.03.5英寸

       &分辨率: 1080*1920 640*1136720*12801280*8001024*600480*854480*800

       &屏幕密度:120dpi(ldpi) 低清、160dpi(mdip)中清(标清) 240dpi(hdpi)360dpi(xhdpi)

     * 手机内存、SDCardCPU、摄像头

     * 手机操作系统版本号

     * 网络制式(GSM\EDGE\WCDMA\HSDPA\TD-SCDMA\WCAMA-2000\TDD-LTE\FDD-LTE)

   

1.3 第一个Android应用程序

1.3.1  创建应用程序流程

* 创建新项目

 

* 配置项目

 

* 配置执行图标属性

 

 

1.3.2  Android应用介绍及项目文件夹结构分析

   * Android应用结构介绍

  Android 应用程序由应用组件(ActivityServiceContentProviderBroadcastReceiver)构成,每个组件是单独的模块,有着不同的入点,系统能够从这些入点进入到你的应用中,组件在AndroidManifest.xml注冊。它们之间松耦合地组织在一起,从而定义你应用的总体功能。

   *项目文件夹结构分析

1.3.3  Android执行过程分析

Ø 项目打包签名

  

Ø 安装APK

    运用adb工具把apk包上传到模拟器(真机)中,文件夹在data\app\

    读取androidManifest.xml清单文件(包名、权限、图标等)

    创建文件夹。在data\data\文件夹下创建以包名为文件夹的文件夹

    写入注冊表, 注冊表文件data\system\packages.xml

Ø 启动APK

    Android系统是一个多用户的Linux系统,应用一旦安装。系统为每一个应用分配一个独立的Linux用户ID,当用户点击应用程序图标或者导航到该应用的组件时。Android框架会创建一个虚拟机实例,开启一个进程,创建一个主线程(UI线程)。再实例化入口组件。进入组件的生命周期

1.3.4  经常使用的命令操作

adb shell   :进入linuxclientshell命令模式

adb install apk文件   :安装apk文件

adb uninstall 包名     :删除模拟器应用

adb devices :列出全部设备

adb push <local> <remote> 把本地的文件拷贝到远端

adb pull <remote> <local> 从远端拷贝文件到本地

mksdcard 大小 <local> 创建sdcard镜像文件

android create avd –name <模拟器名> -target <level> 创建模拟器

emulator –avd avd名 启动模拟器

adb –s <设备名> <命令> 对于有多个设备终端

1.3.5  案例: 应用体验之电话拨号器

实现一个打电话的小程序

* 界面设计

          

* 代码实现

 

     * AndroidManifest.xml中加入打电话权限

       <uses-permission android:name="android.permission.CALL_PHONE"/>

 

1.3.6  DDMS透视图

DDMS(Dalvik Debug Monitor Service)  DVM调试监视服务

& Devices : 查看模拟器设备的状态,模拟器执行的进程

& File Explorer: 文件浏览器(导入、导出文件、创建目录、删除文件等)

& LogCat: 日志查看工具,日志猫

& Emulator Control: 模拟器控制,模拟一些操作(打电话、发短信)

1.3.7  Android參考文档

Ø 參考文档

官网:developer.android.com或本地(%ANDROID_SDK_HOME%\DOC\)

中文參考文档:wiki.eoe.cn     

Ø SDK源代码关联

源代码:(%ANDROID_SDK_HOME%\source),或通过SDK Manager.exe 从官网下

& Eclipse中选中任一系统API,按F3或者CTRL+单击 ,之后找到Java Source Addachment 。指定源代码位置就可以

& 选择项目中的android.jar包,右键点击属性。之后找到Java Source Addachment ,指定源代码位置就可以

二、UI控件与布局

2.1  ActivityViewWindow关系

    *  android.app.Activity

ActivityAndroid四大组件之中的一个,它通过内部的成员变量Window对象来展

示一个与用户交互的界面,界面中的View控件捕获事件。通过WindowManagerService传递消息。Android框架再回调Activity中与捕获事件相关联的方法。从而实现与用户的交互。Activity扮演的是一个控制器的角色

     *  android.view.View

& View:视图,是用户接口组件的基本构建块,它在屏幕中占用一个矩形区域,它是全部UI控件的基类,如一个button或文本框。

View负责图形界面渲染及事件处理

& Android已经为我们提供了一系列的标准UI控件供我们直接使用,同一时候,我们也能够通过继承于ViewView的子类,来实现我们自己定义的UI控件

& View及其子类的关系

  

 

 

 

 

 

      & View经常使用的操作

        Set properties       设置属性  

        Set focus            设置焦点

        Set listeners        设置监听

        Set visibility       设置是否可见

 

*  Window

    WindowAndroid中的窗体。表示顶级窗体,也就是主窗体,每个主窗体都拥有一个View。称之为DecorView(装饰视图),它是主窗体的顶级View(DecorView必须是一个布局容器,由于它要容纳其他的View)。当Activtity调用setContentView()时。实际就是调用Window对象的setContentView()方法,运行该方法。把用户定义的View加入到DecorView中,终于完毕对View的展示。

2.2 认识经常使用UI控件(widget)

    Android平台提供了一套完备的、功能强大的组件化模型用于搭建用户界面,这套组件化模型以View ViewGroup这两个基础布局类为基础。平台本身已预先实现了多种用于构建界面的View子类和ViewGroup子类。他们被分别称为部件(widget)和布局(layout)。

部件(widget)包含ButtonTextViewEditTextListViewCheckBoxRadioButtonGallerySpinner

2.3 布局

2.3.1 ViewGroup

    ViewGroup是一个特殊的View,可以容纳其他的View(子控件)。它是布局和视图容器的基类

     * ViewGroup.LayoutParams 布局參数类属性:

       android:layout_width 相对于父控件的宽度 (wrap_content, match_parent,fill_parent)

       android:layout_height 相对于父控件高度 (wrap_content,match_parent,fill_parent)

     * ViewGroup经常使用的方法

       addView(): 向视图组加入View

       removeView():从视图组移去View

       getChildCount:获得视图组子控件的数量

       getChildAt()  : 获得详细某个子控件

   * Android的显示单位

       & px (pixels)像素   比方480*800像素

& dip或dp (device independent pixels)设备独立像素

           dp与设备硬件有关,执行时依据屏幕密度转化为对应的px,终于由px值确定显示区域大小,推荐使用它

& sp (scaled pixels — best for text size)比例像素

          主要处理字体的大小,能够依据系统的字体自适应,推荐使用

2.3.2 布局

  布局用于定义一个用户接口的可视结构,比方Activity、应用小部件等。

  Ø 布局的实现方式

    *  通过XML声明UI元素

      1. xml文件里设计布局

        - Attributes设置 : 比方ID Layout Paraments设置等

        - Layout Position设置 :比方控件在父控件的位置:上下左右等

        - SizepaddingMargins :控件高与宽、控件内部间隙、控件之间边距设置

2. 导入布局资源

   比方在Activity中:

   protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main_layout);//设置Activity的内容视图

}

    * 通过Java代码方式

     LinearLayout layout=new LinearLayout(context);//创建一个线性布局对象

layout.addView(new TextView(context));//往线性布局对象中加入一个文本视图子控件

 

   Ø 布局的类别

* cmmon layouts : 普通的布局

该布局提供了唯一的方式去显示已经嵌入在该布局中的视图控件,主要用于有固定界面的布局,包含(LinearlayoutrelativeLayoutTableLayoutGridLayoutAbsolutLayout、  FrameLayoutwebView)

* building layout with a adapter: 动态构建的布局

用一个适配器来动态构建布局。当布局的内容是动态的或者前期决定不了的,通过AdapterView的子类与Adapter(适配器)一起来动态构建布局。

比方:採用ListView来展示联系人列表,通话记录等

 

2.3.3 常见的布局

Ø LinearLayout

线性布局。它的子控件是以单一的行或者单一的列排列。子控件不能重叠,具有方向性(水平、垂直),默认是水平方向,能够设置位置和权重

* 经常使用的XML属性:

  android:orientation 线性布局的排列方向(vertical\horizontal)

android:padding   控件内部的间隙

  android:gravity    控件内部的排列位置 (center_verticalcenter_horizontal等)

android:layout_gravity      位置

  android:layout_margin_top   与顶部的边距

android:layout_weight      权重

* 注意点:

 - 修饰控件属性时,有layout与无layout的差别

   有layout。表示布局属性修饰,它相对于父控件或者父控件中的其它子控件的属性修饰,

   无layout。它仅仅针对控件本身,是对该控件内部元素的修饰

 - 权重

   它是线性布局或者它的子类所特有的属性修饰。它针对的是子控件的宽和高的设置

   先预留出没有设置权重的控件的宽或者高,之后对相对于父控件剩余的空间(宽或者高)按权重(比例)分配

Ø FrameLayout

帧布局被设计成在一个屏幕区域显示一个单一的项(single item)。通常FrameLayout显示一个单一的子控件,它支持的布局属性不够丰富。一般通过layout_gravity来设置子控件的位置。

FrameLayout的子控件被绘制在一个堆栈中,近期加入进来的子控件在堆栈的顶部

Ø TableLayout

  表格布局,是LinearLayout的子类。以行和列的形式存放子控件,它通常由多个TableRow布局控件组成,TableRow由多个单元格(cell)组成,每一个cell设置为View对象 。表格布局的子控件能够设置权重,可是不能设置方向

Ø GridLayout

      网格布局,android 4.0以后出现,布局使用虚细线将布局划分为行、列和单元格,也支持控件在行、列上都有交错排列。有方向性,默觉得水平方向,相对于TableLayout。渲染速度更快。更灵活。

     对于低版本号要使用GridLayout,需加入向下的支持库v7

    xmlns:app="http://schemas.android.com/apk/res-auto"

* 经常使用的XML属性:

  android:columnCount     设置列数

  android:layout_row       控件的起始行位置

  android:layout_column    控件的起始列位置

  android:layout_rowSpan   控件跨越行数

  layout_columnSpan       控件跨越列数

  layout_gravity=fill     与layout_rowSpan或columnSpan结合使用,表示填满所跨越的行或者列

Ø AbsoluteLayout

   绝对布局。子控件的位置以绝对的位置定位。子控件之间能够重叠,相对于其它布局,缺少灵活性,不建议使用

* 经常使用的XML属性:

  android:layout_x : 相对于父控件的x坐标位置

  android:layout_y : 相对于父控件的y坐标位置

Ø RelativeLayout

   相对布局,子控件的位置关系能够通过子控件与父控件、子控件与子控件来确定。子控件之间位置能够重叠,拓展性好。灵活方便,是使用最多的布局方式

* 经常使用的XML属性

android:layout_toLeftOf="@+id/name"    指定控件的左边

android:layout_toRightOf="@+id/name"   指定控件的右边

android:layout_above="@+id/name"      指定控件的上边

android:layout_below="@+id/name"      指定控件的下边

 

android:layout_alignLeft="@+id/name"    与指定控件左对齐

android:layout_alignRight="@+id/name"   与指定控件右对齐

android:layout_alignTop="@+id/name"    与指定控件顶部对齐

android:layout_alignBottom="@+id/name" 与指定控件底部对齐

 

android:layout_alignParentLeft="true"     与父控件的左边对齐

android:layout_alignParentRight="true"    与父控件的右边对齐

android:layout_alignParentTop="true"     与父控件顶部对齐

android:layout_alignParentBottom="true"  与父控件底部对齐

 

android:layout_centerHorizontal="true"    在父控件中水平居中

android:layout_centerVertical="true"      在父控件中垂直居中

 

Ø 案例:简易计算器界面制作

运用GridLayout布局设计简易计算器界面

 

Ø 案例:短信发送器设计与实现 

实现一个发短信的android小程序

 (要求布局管理器为相对布局)

* 界面设计

  

* 代码实现

  

* AndroidManifest.xml中设置发短信的权限

  android:name="android.permission.SEND_SMS"/>

 

 

 

 

三、  Android事件驱动机制

  一般,用户常常会通过界面与应用交互,Android框架採用事件驱动的形式与用户交互,那怎样处理用户界面中触发的事件?

能够通过从用户交互的View设置事件监听器的方式来实现对事件的处理。一个事件监听器是View类中一个包括单一回调方法的接口。当注冊了监听器的View发生了相应的监听事件时。Android框架就会回调相应的监听方法。

 

   * 常见的用户事件

     点击事件、选择事件、触屏事件、长按事件、按键事件

3.1  点击事件

单击事件是事件机制中最常见的事件,通过对控件绑定View.OnClickListener 实现单击事件的监听

3.1.1 点击事件四种书写方式

      & 私有类实现方式

      & 匿名内部类实现方式

      & 布局中对控件加入android:onClick

      & Activity实现监听接口

*  案例:对button按键监听

对四个button实现监听,分别用四种不同的书写方式实现单击监听事件

* 界面设计

  

* 代码实现

  

 

  

3.2  选择事件

3.2.1 复选事件

   复选事件的监听接口:CompoundButton.OnCheckedChangeListener

   复选控件CheckBox 有两种状态:选中与未选中状态。对复选控件

* 案例:明密文切换

  通过对CheckBox控件的复选监听,实现对EditText内容明密文切换

  * 界面设计

     * 代码实现

       

 

3.2.2 单选事件

   单选事件的监听接口:RadioGroup.OnCheckedChangeListener

   RadioButtonRadioGroup组合使用才干实现单选功能

* 案例:选择字符集

  通过对RadioButton控件的选择监听,实现对字符集的选择

  * 界面设计

     * 代码实现

   

3.2.3 下拉列表选择

   下拉事件的监听接口:AdapterView.OnItemSelectedListener

* 案例:城市选择

  通过对Spinner下拉列表监听,实现对城市的选择

  * 界面设计

     * 代码实现

3.3  长按与触屏事件

  长按事件监听接口:View.OnLongClickListener

  触屏事件监听接口:View.OnTouchListener

* 案例:长按图标设置手机桌面壁纸

clearWallpaper :清除桌面壁纸

setWallpaper(BitMap bitmap) :设置桌面壁纸

设置壁纸要加入权限:

<uses-permission android:name="android.permission.SET_WALLPAPER"/>

     * 代码实现

3.4  键盘事件

  Activity实现了KeyEvent.backcall接口

  onKeyDown(int keyCode,  KeyEvent event) :当键按下去触发

  onBackPress():当返回键按下去触发  。Activity的方法

  模拟器常见的按键:

       Back 返回键

       Home 手机屏幕桌面

       Ctrl+F11      切换模拟器横竖屏幕

       F2 手机菜单

       F3           电话面板

       F8           手机网络开关

 

 

四、  Android高级UI

4.1  ProgressBar

ProgressBar 进度条。经常使用于文件下载进度显示、系统初始化进度等,默认情况是没有进度值的(转圈圈)

* 提示点:

         style="@android:style/Widget.ProgressBar.Horizontal" 样式设置

         setProgress(int) 设置当前进度值

         getProgress() 得到当前进度值

         setMax(int) 设置最大值

案例:通过button设置进度条进度

    * 界面设计:

       

* 代码实现

  

 

  

4.2  RatingBar

RatingBar 评分进度条,经常使用于对商品、用户的评价,比方惬意度调查等

* 提示点:

       setOnRatingBarChangeListener 设置监听器

       setNumStars 设置星星的个数(设置总分)

       setStepSize 设置分数间隔

       getRating 获得当前的分数值

       setRating 设置当前的分数值

案例:对欧冠精彩程度打分

    * 界面设计:

       

* 代码实现

  

4.3  ToggleButton

 ToggleButton:开关button,它是CompoundButton的子类,实现开与关的效果,比方蓝牙开关、wifi开关、声音开关等

* 提示点:

  - 实现的监听接口:CompoundButton.OnCheckedChangeListener

    该接口是监听开关button状态的改变

  - toggle() :取反操作

- xml属性设置

textOn: 表示状态为开的提示文本

textOff: 表示状态为关的提示文本

案例:设置声音开关

   * 界面设计

                    

* 代码实现

  

 

4.4  ScrollView

ScrollView:滚屏视图,它是FrameLayout的子类,可以被用户滚动的布局容器。它仅仅能拥有一个子控件,常常应用于一个垂直方向的线性布局中。

ScrollView仅仅支持垂直滚动,对于须要水平滚动,则用HorizontalScollView

 

4.5  ListView

 ListView 列表框,经常使用控件,用来显示同样数据结构的批量数据。比方:从数据库获取的数据列表,从网络解析的批量结构数据,一般都会採用ListView展示数据,系统中的设置、未接来电、通信录等显示可採用ListView进行展示

 用ListView展示数据的四个步骤:列表项描写叙述、初始化数据、适配器数据装配、设置适配器

 

案例:在ListView中显示好友列表

    * 界面设计与分析:

       

* 代码实现

  

 

 

 

五、Android消息提示机制

在某些情况下。可能须要你去通知用户发生在你应用中的事件,当中一些事件须要用户响应。有的则不须要。Android框架通过消息机制非常好的完毕上述的需求。

比方:

- 当一个事件完毕时(比方保存文件),须要显示一个简短的消息来确认保存成功

  - 假如应用正在后台执行,且须要用户注意。那么该应用须要创建一个通知以方便用户做出响应

  - 假如用户要操作一个危急的操作,则应该创建一个对话框通知,再一次确认用户的操作

常见的消息提示方式有:

  - Logcat(日志猫)

  - Toast(瞬时提示)

  - Dialog(对话框)

  -Notification(通知)

5.1  Logcat日志

    * 级别 :vdiwe 级别由低往高

      - verbose :混淆的 ,全部信息都能够输出,级别最低

      - debug :调试级别

      - info:信息级别

      - warning:警告级别

      - error :错误级别

     * 加入过滤器 依照Tag进行过滤

     * System.out.println()Log输出之间的差别

       - System.out.println()输出的信息  等级是info级别。标记tagSystem.out

       - System.out.print()输出信息 须要System.out.flush()刷缓存输出

5.2  Toast瞬时提示

   Toast通知是一种浮如今屏幕上层的消息提醒。它仅仅填充消息所须要的空间,而当前正在执行的活动仍然保持其自身的可见性和交互性。这样的通知自己主动淡入淡出且不接受交互事件

Ø 通过代码自己定义Toast

   

   * 代码实现

     

 

Ø 通过XML自己定义Toast

  * LayoutInflate  :xml布局文件实例化为View对象

    

5.3 对话框

   对话框一般是一种显示在当前活动之上的小窗体,这时候下层的活动将失去焦点,由对话框来实现与用户的交互,经常使用于加入简单的数据或对操作进一步确认等。比方删除联系人信息、加入类别等,但对话框不宜过多,会影响用户体验

    常见的对话框有:标准对话框、单选对话框、复选对话框、自己定义对话框

5.3.1 标准对话框

     标准对话框是使用最多的一种对话框样式,包括对话框图标、标题、提示系统、确认和取消。

     * 创建标准对话框流程:

1. 生成对话框构建器对象AlertDialog.Builder

2. 设置图标Builder.setIcon

3. 设置标题

4. 设置提示信息

5. 加入确认与取消button

6. 对确认与取消button中加入监听,实现对话框的业务逻辑

         * 案例: 构建标准对话框

           * 界面设计

 

* 代码实现

5.3.2 菜单式对话框

   菜单式对话框适用于单选某个列表项或者对某项数据有几种不同的操作等应用场景

* 关注点:

  & Builder.setItems(items, listener) :设置单选项

items:单选项字符串数组

listener:单选单击监听

       * 运用单选对话框选择Android版本号代号

          * 界面设计

 

* 代码实现

 

5.3.3 复选对话框

   复选对话框适用于以对话框的形式复选某个列表

* 关注点:

  & Builder.setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, OnMultiChoiceClickListener listener)  : 设置复选监听

items:复选项字符串数组

checkedItems:复选项默认值

listener:复选单击监听

         & AlertDialog.getListView() : 得到用于对话框的列表视图—ListView

         & SparseBooleanArray : 稀疏布尔数组,用于映射整数到布尔值 ,与一般的布尔数组不同。下标能够同意有间隙,它比用HashMap映射IntegersBooleans 更有效率

         & ListView.getCheckedItemPositions() 得到选择项的位置信息及其状态 ,返回值:SparseBooleanArray

       * 运用复选对话框选择Android版本号代号

          * 界面设计

 

 

* 代码实现

 

5.3.4 自己定义对话框

   系统对话框太单一。在开发中常须要自己定义对话框

* 关注点:

  & new Dialog(context,theme):以自己定义的样式构建对话框

  & Dialog.setContentView():设置对话框的布局

  & Dialog.findViewById() : 通过findViewById找到对话框布局中的控件

       * 自己定义视图,实现通过对话框输入信息

          * 界面设计

 

* 代码实现

 

 

5.3.5 对话框优化

   Ø 对话框缓存

   同样对话框每次显示的界面都是一致的。能够通过Activity的对话框缓存实现对话框实例的反复利用,达到优化对话框的目的

* 实现原理图

 

Ø DialogFragment

* Fragment :碎片、片段

引入fragments主要目的是用在大屏幕设备上支持更加动态和灵活的UI设计

一个Fragment代表一个用户接口的行为或者部分行为,把几个Fragment混合到一个Activity,能够创建一个多个页面的UI并能够在多个Activity中复用一个Fragment,碎片必须总是嵌入到一个活动(activity)中。而且它的生命周期直接受到Activity的生命周期的影响。

fragment 想象成一个activity的模块化区域, 有它自己的生命周期, 接收属于它的输入事件, 而且能够在activity执行期间加入和删除

* DialogFragment :对话框碎片  

  用于显示一个对话框窗体的Fragment。它浮于Activity窗体上面,该对话框的显示依赖于Fragment的生命状态

* 实现步骤

  - 创建一个类,继承DialogFragment。重写onCreateDialog方法。在该方法中完毕对话框的创建

  - Activity中创建DialogFragment实例,并调用show()方法完毕对话框的显示

    能够通过DialogFragment.setArguments()\getArguments()传递和接收參数 

六、单元測试

   在实际开发中,开发android软件的过程须要不断地进行測试。而使用Junit  測试框架。则是正规的Android开发的必用技术,Android非常好封装了Junit測试框架。能够模拟发送事件和检測程序处理的正确性

   * Android单元測试实现流程

     1. 加入測试类库

       在AndroidManifest.xml <application> 节点 加入測试类库

        <uses-library android:name="android.test.runner"/>

     2. 设置測试环境

       <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="cn.itcast.filestore"/>

     3. 编写測试类

- 继承AndroidTestCase

- 获取上下文getContext()

- 使用断言 assertEquals()

- 查看測试效果

 

 

七、Android移动存储

各种Android移动的主要任务是处理数据。怎样将须要处理和处理好的有效的存储起来是一个亟待解决的问题。Android系统提供了很丰富的移动存储方案。

* 常见移动存储方案:

    手机内部存储

     手机外部存储

     SharedPreferences

     SQLite

     ContentProvider

     网络

 

 

7.1 文件存储

7.1.1 手机内部存储

手机内部存储,默认在/data/data/<包名>/files 目录下存放文件

* 手机内部存储的特点:

  & 存放本应用中的私有数据

  & 当应用卸载时,/data/data/<包名> 这个文件夹会同步删除,即手机内部存储的文件

会删除

* 关注点:

      & Context.openFileOutput(String name, int mode)

- 往手机内部存储中以某种模式写文件

- name :文件名称

- mode :文件操作模式

- returnFileOutputStream

- 文件存放在/data/data/包名/files/

      & Context.openFileInput(String name) 从手机内部存储中读取文件

- 从手机内部存储中读文件

- name:文件名称

- returnFileInputStream

      & getCacheDir() 方法用于获取/data/data/<package name>/cache文件夹

      & getFilesDir() 方法用于获取/data/data/<package name>/files文件夹

* 文件操作模式

权限

说明

Context. MODE_PRIVATE【默认】

私有权限。仅仅有本Android应用可用

Context. MODE_WORLD_READABLE

全局读权限,其它Android应用仅仅能够读取

Context. MODE_WORLD_WRITEABLE

全局写权限,其它Android应用可写

Context. MODE_WORLD_READABLE+

Context. MODE_WORLD_WRITEABLE

全局读写全新,其它Android应用可读可写

Context. MODE_APPEND

追加模式。在些数据的时候在已有文件后追加写,默认是私有权限仅仅有本应用可读可写

7.1.2  外部存储

全部兼容Android的设备都支持一个可共享的“外部存储(external storage),可用来保存文件。

这能够是一个可移动的存储设备(比方SD卡)或者一个内部的(不可移动的)存储。

保存在外部存储的文件是可全局读写的。

* Sdcard存储的特点:

  & 依赖于Sdcard,使用SDCard存储,需先检測其状态

  & 存在Sdcard的文件是可全局读写的

  & 写入Sdcard时,须要权限

* 关注点:

  & Environment.getExternalStorageState()  取得外部存储状态

  & Environment.getExternalStorageDirectory() 取得外部存储根路径

  & 写入外部存储的权限

     android.permission.MOUNT_UNMOUNT_FILESYSTEMS

android.permission.WRITE_EXTERNAL_STORAGE

    * 外存路径描写叙述

      & 取得外部存储的公共共享存储路径

       Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

     & .在外存中存放应用的私有文件,当应用删除时,该内容会同步删除 :

        context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

     文件夹: /android/data/<包名>/files/<类型>

     &.在外存中存放应用的私有缓存文件 ,当应用删除时,该内容会同步删除

          context.getExternalCacheDir()

         文件夹:/android/data/<包名>/cache

     &.取得外存的根路径

         Environment.getExternalStorageDirectory()

Ø 案例 :文件存储

      在Activity界面中编辑某文件,实现对该文件在手机内部存储及SDCard的存取

  * 界面设计

    

* 代码实现(手机内部存取)

 

* 代码实现(SDCard存取)

 

 

7.2  SharedPreference

   SharedPreferences,是一个很轻量的数据存储方式,以xml的形式存取简单的键值对数据。数据类型包含(ints,floats,boolean,strings,longs,Set<String>(android 11以后)),存放位置:/data/data/<包名>/shared_prefs。存放的是应用私有的数据,主要用于软件偏好设置。简单信息存取等

   * 获取SharedPreference对象

-  Context.getSharedPreferences(String name,int mode)

    name:指定XML文件名称,不须要指定.xml后缀。name存在则打开,没有则创建

    mode:文件的操作模式,见文件存储的文件操作模式表格

  -  Activity.getPreferences(int mode)

    name为默认值:即当前訪问的Activity的类名

   * 操作SharedPreference对象

     & 取得參数值

- SharedPreference.getString(key,defValue) 取得參数值,类型为字符串

- SharedPreference.getBoolean(key,defValue) 取得參数值。类型为布尔型

     & 存储參数值

- Editor edit = SharedPreferences.edit();    // 获取编辑器

       - edit.putString(key, value);    // 存储字符串数据

       - edit.putBoolean(key, value);  // 存布尔数据,

       - edit.commit();   // 提交新值

  Ø 案例 :运用SharedPreference保存用户登录信息

         要求:

1.账号password验证成功。则进入还有一个Activity

            2.选中复选框,则用户登录时。把账户及password信息存入SharedPreference

            3.应用下次启动,根据存储的复选框状态值,决定是否填充账户与password信息

            4.对存入SharedPreference的值对信息加密

      * 界面设计

         

* 代码实现

 

 

 

 

7.3  Pull解析

   XML文件是很重要的数据格式,它能够用来作配置文件。存储数据等,Android中能够通过SAX、DOM、PULL来解析 XML数据

7.3.1  pull解析XML文件

* pull解析:

Xml文件边导入内存,边解析。採用事件驱动机制,当解析到一个节点。返回的是该节点的事件类型,且不会继续往下解析。需手动指向下一个节点,才干继续往下解析。直到文档的结尾。

Android默认採用pull解析。

    * 事件类型:

      - START_DOCUMENT : 開始文档

      - START_TAG : 開始标签

      - END_TAG : 结束标签

      - END_DOCUMENT : 结束文档

7.3.2  pull生成XML文件

Ø 案例:用pull解析及生成XML文件

* 界面设计

  

* 代码实现 (pull解析)

* 代码实现 (pull生成xml)

 

 

 

7.4  Sqlite数据库

   Android平台上,集成了一个嵌入式关系型数据库—SQLite,它是一种很轻量的数据库管理系统,SQLite3支持 NULLINTEGERREAL(浮点数字)、TEXT(字符串文本)BLOB(二进制对象)数据类型。SQLite通过文件来保存数据库,一个文件就是一个数据库

* 经常使用类介绍

  & SQLiteOpenHelper

数据库辅助抽象类。通过实现它的子类能够创建数据库以及实现版本号更新,通过getWriteableDatabase获得getReadableDatabase获取数据库訪问类

  & SQLiteDatabase:数据库訪问类

    通过数据库訪问类,能够实现对数据库的增删改查等操作

 

7.4.1  Android创建Sqlite数据库

     SQLite数据库是在第一次调用的时候创建数据库的

创建数据库的步骤:

  1.定义一个db辅助类。继承SQLiteOpenHelper抽象类,通过构造方法设置数据库名及版本号信息

  2. 重写onCreate()方法,该方法仅仅会在数据库第一次创建的时候调用。在此方法中适合做数据库初始化操作,比方创建数据表等

  3. 重写onUpGrade() , 当数据库版本号更新时调用,适合做表结构的改动或者加入删除表

* 參考代码:

7.4.2  SQLite数据库增删改查

     * 加入记录

       

     * 删除记录

  

   *  查询

       

     *  更新记录

 

7.4.3  SQLite事务处理

   

7.5 内容提供者

7.5.1 内容提供者特点介绍

& Android四大组件之中的一个,没有图形界面

& 共享数据给第三方应用程序。统一数据訪问方式

& 线性安全,Android系统为每一个 ContentProvider提供一个实例(单列模式),通过ContentResolver訪问ContentProvider

7.5.2  ContentProvider实现流程

    1.  准备须要共享的数据,通常是sqlite数据

     2. 创建一个类。继承ContentProvider。实现第三方应用訪问数据的方法(增删改查)

     3. AndroidManifest.xml 进行注冊,而且设置android:autorities属性:认证(在系统中该内容提供者的唯一标识)

     4. 第三方应用訪问ContentProvider。 通过Context.ContentResolver(内容訪问者)进行訪问,比方:ContentResolver.insert(Uri,ContentValues);

7.5.3 经常使用API介绍

     *  Uri:(统一资源标识符)表示要操作的数据

由两部分组成:内容提供者的标识、详细要訪问什么,也就是路径

              content://cn.itcast.sqlite.provider.books/student/

       *  UriMatch: 用来匹配Uri的 工具类

           UriMatch.addUri(Uri);//注冊Uri

       UriMatch.match(Uri);匹配Uri

       *  ContentUrisUri内容解析

ContentUris.withAppendedId(Uri,id) : Uri尾部加入id

ContentUris.parseIdUuri) :解析Uri。获取Uriid部分

 

Ø 案例:通过ContentProvider共享数据库

books.db数据库的book表通过ContentProvider实现数据共享。第三方应用能够对book表实现增删改查操作

* 通过UriMatch注冊Uri

  

  

* 实现查询操作接口

  

  

 

 

 

 

 

* 通过获得訪问数据类型接口

  

  

 

 

 

* 实现插入操作接口

  

* 实现删除操作接口

  

  

 

  

 

 

 

 

 

 

 

* 实现更新操作接口

  

 

 

 

 

 

 

 

 

 

* 第三方訪问ContentProvider

  

八、菜单设计

8.1 选择菜单

    一个Activity最多仅仅能拥有一个选择菜单,当选择菜单第一次訪问的时候创建,该Activity销毁没有销毁的情况下。仅仅创建一次

 * 创建选择菜单

       onCreateOptionsMenu(Menu menu)

     * 监听选择菜单

       onOptionsItemSelected(MenuItem item) 

8.2 上下文菜单

一个组件能够绑定一个上下文菜单。上下文菜单每次弹出。都会又一次创建一次

* 注冊上下文菜单

    注冊上下文菜单的两种写法

         //registerForContextMenu(bookList);

     // bookList.setOnCreateContextMenuListener(this);

     * 创建上下文菜单

         &  onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)

           參数:menu:要创建的上下文菜单

             v: 选择项的视图(ListViewItem)

             menuInfo: 额外的菜单信息,依赖于选择的视图(V

         & 获取弹出上下文菜单的选项视图信息

            //通过适配器上下文菜单信息类来获取 被选中的菜单项的数据信息

   AdapterContextMenuInfo adapterInfo=(AdapterContextMenuInfo) menuInfo; 

     * 监听上下文菜单

         onContextItemSelected(MenuItem item)

        //通过适配器上下文菜单信息类来获取 被选中的菜单项的数据信息

   AdapterContextMenuInfo adapterInfo=(AdapterContextMenuInfo) item.getMenuInfo(); 

8.3 操作条(ActionBar)

* 1.Action Bar特点

操作栏在Android 3.0版本号以后出现,是一个窗体功能用于确定应用程序和用户的位置,并提供给用户操作和航模式Action Bar被觉得是新版Android系统中重要的交互元素

* 2、Action Bar分成四个区域

- App Icon:可显示软件icon。也可用其它图标取代。

当软件不在最高级页面时,图标左側会显示一个左箭头,用户能够通过这个箭头向上导航。
  - 视图切换:假设你的应用要在不同的View中显示数据。这部分同意用户来切换View。

一般的作法是用一个drop-down菜单或者是Tab Controls。假设仅仅有一个界面,那这里能够显示App Title或者更长点的商标信息
  - Action Buttons:这个放最重要的软件功能,放不下的button就自己主动进入Action overflow了。
  -  Action overflow:把不经常使用的Actions移到Action overflow

 

 

* 3、Action Bar经常使用的交互操作

   - 选择操作项

     与选择菜单一致,都是使用同样的api来创建和监听操作项

   - 操作导航选项标签

     选项标签要与Fragment相结合,实现界面切换的效果

     1. 加入标签 : ActionBar.Tab

     2. 监听标签 : ActionBar.TabListener

 

Ø 案例:通过菜单操作内容提供者的数据

      * 界面设计

     

     * 代码实现(更新书籍信息)

      

    * 刷新数据操作

九、 自己定义适配器

9.1 为什么要自己定义适配器

     想操作列表项的界面和数据

      * 列表视图、初始数据、列表项布局关系图

       

9.2 怎样自己定义适配器

     

9.3 自己定义适配器优化 

1. 当某个item进入视野范围内时。就会调用adaptergetView方法。又一次渲染item。之前我们在每次渲染item的时候都又一次实例化item的布局文件。创建一个View。这样会产生非常多的对象,性能不佳

2. 我们尝试使用以下这样的循环利用的方案

 

1> 如果我们的屏幕刚好仅仅能放下3item

2> 当从状态1—>状态2,有4item同一时候出如今屏幕中,因此这4ItemView都是不同的对象

3> 当从状态2—>状态3item-0消失在视野中

4> 当从状态3—>状态4。我们能够考虑把之前的item-0移动到item-4的位置。由于item-0item-4不会同一时候出如今我们视野范围中

5> 当从状态4—>状态3,我们能够考虑把之前的item-4移动到item-0的位置

3. 再来看public View getView(int position, View convertView, ViewGroup parent)中的convertView參数,这个是系统帮我们传递进来的,它就代表当前可循环利用的ItemView

4. 注意:尽管性能有提升,可是在渲染item的时候。一定保证当前item要全然覆盖可循环利用item的数据,由于循环利用item可能会造成旧数据残留。

 

十、Intent意图

   Intent负责相应用中一次操作的动作、动作涉及数据、附加数据进行描写叙述,Android则依据此Intent的描写叙述。负责找到相应的组件。将 Intent传递给调用的组件,并完毕组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。

10.1  Intent表现形式

   * 调用Activity startActivity(intent) startActivityForResult(Intent)

    * 调用Service:服务 startServiceintent\bindService(intent)绑定服务

* 发送广播 :sendBroadcast(intent)发送无序广播

sendOrderedBroadcast(Intent)发送有序广播

10.2  Intnet 属性设置

   * setAction: 设置动作

ACTION_MAIN ACTION_VIEWACTION_GET_CONTENTACTION_EDIT

    * setData: 设置数据  :Uri格式的数据。标准数据

    * setType:设置数据的类型 :MIME image/*,video/* ,text/plain

* addCateGory: 加入你要调用的组件的类别

  CATEGORY_LAUNCHER    CATEGORY_HOME  

CATEGORY_BROWSABLE  CATEGORY_DEFAULT

   * 案例:在本应用中实现站点的浏览

      

10.3  显式意图与隐式意图

    * 显示调用是直接指定类名,Android不用再去解析intent

    * 隐式调用须要设置actiondatacategorytype,再有Android解析你的意图

对于本应用中的组件要实现隐式调用。须要在AndroidManifest.xml中配置<intent-filter>

  * 案例:显示调用第三方应用Activity组件

      

 

10.4  Intent附带数据

 * 两种写法 :

& 通过Intent.putExtrakeyvalue)加入

& 通过bundle加入

 * 加入额外数据

    

* 在目标组件中获取上一个组件传递过来的额外数据

十一、Activity活动

11.1  Activity特点介绍

活动。四大组件之中的一个,也是最重要的组件。它通过内置的Window对象来展示一个与用户交互的界面,它的操作都与用户有关。一般一个布局针对于一个Activity界面

View控件捕获事件信息,WindowManagerService传递消息,再由Android框架回调Activity的对应监听方法实现与用户的交互

11.2  開始Activity以及得到返回结果

   *  startActivity(Intent)  :开启一个新的Activity,它将放到活动栈的栈顶

* startActivityForResult(Intent,int) :开启一个新的Activity。当新的Activity结束时,通过setResult(int,Intent)把结果回传给调用者,调用者通过onActivityResult()处理回传结果

* 案例:设置图像视图控件的前景图片

      点击图像视图控件。进入图片浏览界面,把选定好的图片作为图像视图控件的前景图片

* 參考代码

 

11.3  Activity生命周期

    应用中的活动是由活动栈进行管理的,当一个新的Activity启动后,它会处于栈顶的位置。与用户进行交互,处于执行的状态;先前的Activity会移到它的下方,处于暂停或者停止状态

   * Activity生命周期

       - 全然生命周期

           自第一次调用onCreate()開始,直至调用onDestroy()为止。

ActivityonCreate()中设置全部“全局”状态以完毕初始化。而在onDestroy()中释放全部系统资源。

       - 可见生命周期

           自onStart()调用開始直到对应的onStop()调用结束。在此期间。用户能够在屏幕上看到Activity,虽然它或许并非位于前台或者也不与用户进行交互。在这两个方法之间,我们能够保留用来向用户显示这个Activity所需的资源。

       - 可交互的生命周期

           自onResume()调用起,至对应的onPause()调用为止。

在此期间。Activity位于前台最上面并与用户进行交互。

Activity会常常在暂停和恢复之间进行状态转换。

   

   *Activity生命周期状态

    Activity有四个生命周期状态。状态之间改变须要回调对应的生命周期方法来完毕

       - 执行状态

       - 暂停状态

       - 停止状态

       - 销毁状态

   * 生命周期方法

       - onCreate(): 创建方法

       - onStart(): 開始方法

       - onResume(): 获得焦点方法

       - onPause()  :暂停方法

       - onStop()  :停止方法

       - onRestart()  :又一次启动方法

       - onDestroy() :销毁方法

     

   * 应用场景:

       - onCreate(): 创建Activity时调用,一般在这里做初始化的操作,比方控件的初始化,绑定数据到列表中等

   - onDestroy():销毁,在这里释放资源 MediaPlayer.release(), 关闭数据库连接

 - onStart() 開始方法 :一般注冊广播监听 。绑定服务  onStop()注销监听 ,取消服务绑定

   - onpause() onResume() 。这两个方法会常常调用,这里不易写耗时的操作。

   一般在这里对持久化数据的保存 。停止动画以及耗CPU的事情;onResume则相反

11.4  Activity管理及启动模式

     对Activity实例的管理: 通过任务栈的形式来管理(TaskStack

   * standard :标准模式(每次激活,都会创建一个Activity实例)

   * singleTop :栈顶模式 :假如要激活的Activity它的实例刚好在栈顶的话。就不用再又一次创建

   * singleTask: 单任务模式 : 假如任务栈有该Activity的实例。就不须要又一次创建。由于该Activity要与用户交互,全部在该Activity实例前面的Activity都会弹出堆载

   * singleInstance: 单实例模式 :主要用于实例共享,会单独开辟一个任务栈来存放该实例,比方浏览器的Activity

11.5  onSaveInstanceState()和 onRestoreInstanceState()

  ActivityonSaveInstanceState() onRestoreInstanceState()并非生命周期方法,它们不同于 onCreate()onPause()等生命周期方法。它们并不一定会被触发,Activityeasy被销毁时(如:内存不足、用户直接按Home键、跳转到下一个Activity、屏幕切换(横竖屏))onSaveInstanceState()才会被调用。可是当用户主动去销毁一个Activity时,比如在应用中按返回键,onSaveInstanceState()就不会被调用。由于在这样的情况下,用户的行为决定了不须要保存Activity的状态。通常onSaveInstanceState()仅仅适合用于保存一些暂时性的状态。而onPause()适合用于数据的持久化保存。

须要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成对的被调用的。onRestoreInstanceState被调用的前提是,activity “确实”被系统销毁了

11.6  Activity程序响应性

   在Android中。应用的响应性被活动管理器(Activity Manager)和窗体管理器(Window Manager)这两个系统服务所监视。

当用户触发了输入事件(如键盘输入,点击button等), 假设应用5秒内没有响应用户的输入事件,那么。Android会觉得该应用无响应,便弹出ANRApplication No Response)对话框

在正常情况下,Android程序会在一条单线程里执行。假设Activity要处理一件比較耗时的工作。应该交给子线程完毕,否側会由于主线程被堵塞。后面的用户输入事件因没能在5秒内响应,导致应用出现ANR对话框。

十二、Android广播机制

   当遇到这些问题:电池低、网络断网、下载完毕或某个图片被捕获,想通知你的用户,那该怎么办?

Android平台中, 通过广播机制能非常好解决这些问题,当遇到某些系统事件时,比方收到短信、电量偏低等,就会以广播的形式发送事件消息,而且Android框架会自己主动唤醒订阅了该广播事件类型的广播接收器来处理,处理完成后,Receiver立即退出。

Android广播机制的特点:

   1. 发送者不必关心接受者的情况,发送者与接收者全然的解耦

   2. 广播事件是系统级别的事件,而我们开发的应用的事件(比方控件的点击事件),它是属于应用级别的事件

   3. 系统内置了大量的广播事件,订阅系统的广播事件能够丰富我们应用的功能

   4. 广播机制主要解决的是应用程序之间通信的功能

12.1  Android广播接收器

   * 特点:

     1. Android四大组件之中的一个,是唯一能够动态注冊的组件

     2. 没有图形界面,可以自启动。在主线程执行

     3. BroadcastReceiver组件生命周期比較短,10秒左右,运行完组件的onReceive()方法后后会马上销毁。所以广播接收器组件应该扮演一个网关的角色。仅仅作简单的信息处理。比方发通知或者Toast;对于复杂的业务应该开启一个Service或者在还有一个应用中去完毕业务

    * 执行流程

  首先把要发送的信息及动作封装在Intent中,由系统事件机制触发广播(比方:日期改变、电池电量低、网络断网、收到短信等)或者自己通过Content.sendBroadcast(Intent)发送广播。当Intent发送以后。系统根据发送的Intent信息与已经注冊的广播接收器组件进行匹配。若匹配成功,则实例化对应的BroadcastReceiver组件。调用onReceive(Context curContext, Intent broadcastMsg)方法。执行完成,销毁广播组件。

 

 

      

12.2 自己定义广播接收器

  * 自己定义广播接收器实现流程

1. 定义类,继承BroadcastReceiver,并重写onReceive()方法

2. AndroidManifest.xml注冊广播接收器

3. 订阅广播事件

  * 案例:自己定义能监听日期改变的广播接收器

* 參考代码

 

12.3 无序广播与有序广播

   * 无序广播

全部的广播接收器执行在一个没有定义的顺序,不能屏蔽结果,不能改动广播, 无法终止广播 ,可通过Context.sendBroadcast发送无序广播

* 有序广播:

有序广播在同一时间传送到一个接收器。因为每一个接收器依次运行。它能够结果传播到下一个接收器,或者它能够全然中止的广播。需定义优先级优 先级别在 intent-filter 中的 priority 中声明 ,-1000 1000 之间 , 值越大 , 优先级越高 . 接收者能够截断广播等,可通过Context.sendOrderBroadcast发送有序广播。

android:priority :设定广播接收器的优先级

abortBroadcast() :截断广播、终止广播传递

 

    * 案例 :短信监听器

      * 要求:

1.该应用没有界面。也不能在手机应用程序列表中出现

2.可以获取短信内容及发信人电话号码

3.实现自己主动回复功能

4.截断短信,系统提供的短信接收器组件不能收到短信

      * 參考代码

     

 

 

      

 

 

 

 

 

 

 

 

12.4 动态注冊广播接收器

   * 应用场景

     通过AndroidManifest.xml注冊广播接收组件。仅仅有当该应用在Android系统中删除才可以注销广播接收组件。有时须要当应用执行时注冊广播接收组件,而应用退出时,注销该广播接收组件,该怎样解决?

能够对广播接收组件实现动态注冊,广播接收器也是唯一能够动态注冊的Android组件。一般在ActivityonStop()注冊广播接收组件,在onResume()中注销广播接收组件。

   * 案例:对监听日期改变的广播接收器组件实现动态注冊

      * 參考代码

    

12.5 广播通知

Notification 是一条显示在应用UI界面之外的通知,一条通知到来时。它首先显示在通知栏中。当对通知往下拉放时,会显示通知的具体信息,当对通知的具体信息框进行点击时,则可通过Intent激活其它组件。实现业务处理。

NotificationAndroid很重要的消息提示机制,常与广播接收器组合使用,实现广播通知,比方:短信通知、软件更新通知等

 

12.6 Android4.0以后版本号的广播机制问题

     在3.1之后。系统的package manager添加了对处于“stopped state”应用的管理,

 指的是安装后从来没有启动过,与此同一时候系统添加了2FlagFLAG_INCLUDE_STOPPED_PACKAGESFLAG_EXCLUDE_STOPPED_PACKAGES

来标识一个intent是否激活处于“stopped state”的应用。

Android默认给全部的广播intent加上FLAG_EXCLUDE_STOPPED_PACKAGES,能在一定程度上避免流氓软件、病毒啊干坏事。还能提高效率。假设用户没有执行过应用。就不会响应了。

  只是对于自己定义的广播接收器我们能够通过setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);这种方法来唤醒处于“stopped state”的程序,对于系统发的广播,则无能为力

 解决的方法:

1. 在你的广播接收器应用中加入一个Activity,让用户执行一次你的应用

2. 通过其它应用发一个自己定义广播事件。intent设置为intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES),即包括停止状态的包也可以被激活,你的广播接收器应用订阅了系统的广播事件,同一时候也订阅了自己定义的广播事件。这样就行激活处于停止状态的广播接收器组件

十三、Service服务

四大组件之中的一个。须要注冊、没有图形界面,生命周期长、不能自启动,须要startService或者bindService来启动服务,默认在主线程执行

 主要用于实现生命周期较长的操作,比方:打印服务、下载服务、音乐服务、更新服务

13.1  Android进程等级

Android系统会尽量维持一个进程的生命。直到终于须要为新的更重要的进程腾出内

存空间。

为了决定哪个进程该终止,系统会跟据执行于进程内的组件的和组件的状态把进程置于不同的重要性等级。

Android进程共分为五个等级。各自是:前台进程(Foreground Process),可视进程( Visible Process), 服务进程(Service Process), 后台进程(Background Process), 空进程(Empty Process)

前台进程等级最高。空进程等级最低,系统须要内存资源时。会优先回收等级低的进程,比方空进程、后台进程等

   * 前台进程

     用户当前正在做的事情须要这个进程。假设满足以下的条件,一个进程就被觉得是前台进程:

    1)这个进程拥有一个正在与用户交互的Activity

2)这个进程拥有一个绑定到正在与用户交互的activity上的Service
3)这个进程拥有一个前台执行的Service — service调用了方法

startForeground().
4)这个进程拥有一个正在运行其不论什么一个生命周期回调方法(onCreate(),onStart(

onDestroy())的Service


 5)这个进程拥有正在运行其onReceive()方法的BroadcastReceiver

   * 可视进程

    一个进程不拥有执行于前台的组件,可是依旧能影响用户所见。满足下列条件时,进程即为可见:
       1)这个进程拥有一个不在前台但仍可见的Activity(它的onPause()方法被调用)
       2)这个进程拥有一个绑定在前台(或者可见)Activity的服务。


    一个可见的进程是极其重要的,通常不会被终止。除非内存不够。须要释放内存以便前台进程执行。

   * 服务进程

一个进程不在上述两种之内,但它执行着一个被startService()所启动的service


虽然一个服务进程不直接影响用户所见,可是它们通常做一些用户关心的事情(比方播放音乐或下载数据)。所以除非系统没有足够的空间执行前台进程和可见进程时才会终止一个服务进程。

* 后台进程

一个进程拥有一个当前不可见的activity(activityonStop()方法被调用)
    这种进程们不会直接影响到用户体验,所以系统能够在随意时刻杀了它们从而为前台、可见、以及服务进程们提供存储空间。

* 空进程

没有执行不论什么component的进程,保留这个进程主要是为了缓存的须要。这样的进程存在的唯一原因是做为缓存以改善组件再次于当中执行时的启动时间

                        服务生命周期图

13.2 全局服务

    一旦服务开启,那么调用者和服务就没有不论什么关系了,因此哪怕调用者被destroy 

    那么服务依然在执行。且不能调用服务内部中的方法。

   * 启动

       startService(Activity方法)  -->onCreate(Service的生命周期方法,当服务不存在调用。用于初始化服务)-->onStartCommand(Service的生命周期方法)

* 交互

   startServiceActivity方法)-->onStartCommand(intent) :通过Intent附加数据进行交互

* 关闭

   stopServiceActivity方法)-->onDestroy(服务的生命周期方法)

13.3 绑定服务

     一旦服务开启,那么调用者和服务就有密切关系了。假设全部client被destroy 

   那么服务也就会被destroy

且能够调用服务内部中的方法。调用者被销毁前,须要对绑定的服务解绑。

    * 启动:bindService(Activity方法) -->onCreate(Service为空调用)-->onBind()

    * 交互:直接在Activity中拿到Service的实例或者Service的代理对象进行操作 

    * 关闭:unBindService(Activity方法)-->OnUnbind()-->ondestroy()

   案例:通过Service实现音乐播放  

13.4  IntentService

这是一个Service的子类,该子类使用线程处理全部启动请求,.你须要做的仅仅是实现onHandleIntent()方法就可以.根据Intent的请求指令运行对应的业务。

* 流程介绍:

1. 从应用的主线程其中创建一个默认的线程运行全部的intents发送给onStartCommand()方法,该线程从主线程分离.

2. 创建工作队列,每次传递一个intent onHandleIntent()方法实现,不必操心多线程.

3. 全部的请求被处理后服务停止,所以你永远都不必调用stopSelf()函数.

4. 默认实现onBind()方法返回null.

13.5  AIDL实现IPC(进程间通信)

Android Interface Definition Language(Android接口定义语言)

因为Android没有一个进程间共享的内存区域。通过AIDL能够实现进程间的通信

 AIDL实现IPC的流程:

      1. 在远程服务端定义aidl文件 。定义好比接口定义。系统工具会自己主动生成对应的java接口

      2. 在服务端的Service中继承该接口的Stub类,作为远程服务的代理对象

      3. 在client中先拷贝服务端的aidl文件。而且放在与服务端包名一致的包以下

      4. 在client通过ServiceConnetion来获得远程服务的代理对象,实现远程进程通信

      5. 在服务端对Service设置IntentFileter,用于远程组件的调用

      6. AIDL是线性安全的,由框架来维护其线性安全

 

 

 

 

 

 

 

 

 

 

 

十四   Android 新特性

14.1Fragment

14.1.1  Fragment介绍

Fragment:片段、碎片, 表现 Activity UI的一个行为或者一部分. 能够组合多个fragment放在一个单独的activity中来创建一个多界面区域的UI,并能够在多个activity里重用某一个fragment.fragment 想象成一个activity的模块化区域, 有它自己的生命周期, 接收属于它的输入事件, 而且能够在activity执行期间加入和删除.

 

14.1.2  Fragment生命周期

    Fragment 必须总是被嵌入到一个activity, 它们的生命周期直接被其所属的宿主activity的生命周期影响.

 

14.1.3  Activity管理Fragment

   *  Activity的布局文件加入Fragment

 

 

posted @ 2017-07-27 21:47  llguanli  阅读(723)  评论(0编辑  收藏  举报