«

Android笔记

时间:2024-3-2 19:46     作者:韩俊     分类: Android


Java
OOP
API(lang包,util包,io包)
包装类-Integer
数据库
JDBC--SQLService
WEB
Html(css,js),(JSP/Servlet)

Android
应用型技术
游戏-->暂时来说国内没什么前途,在技术上来说:图形
功能-->利用设备来实现应用
应用-->淘宝客户端,新浪微博客户端,人人网,优亿市场.....

---------------------------------------------------
环境安装
Android的介绍(版本)
建立一个Android的工程(了解下工程目录)
模拟器(AVD)

Android的历史:
Google在2005年放出消息,要进入移动电话领域
2007年,Google推出Android1.0版(铁臂阿童木)
2009年,Google联合HTC推出第一台Android手机--G1
搭载了Android1.5版
Google为了推出Android,还做了以下事情:
牵头成立了一个开放手持设备联盟,初始参与的厂商有34家
在推出G1之前的半年,举办了全球性质的Android开发者大赛,奖金高达100万美元
2010年,G1,G2的手机总出货量已经超越苹果,接近诺基亚
2011年,仅三星一家的出货量已经超过苹果1倍,而诺基亚。。忘掉吧

法国作家写了一本小说《未来夏娃》

Android1.0版,代号Astro(铁臂阿童木)
Android1.5版,代号Cupcake(纸杯蛋糕)
Android1.6版,代号Donut(甜甜圈)
Android2.0/2.1版,代号Éclair(松饼)
Android2.2版,代号Froyo(冻酸奶)
Android2.3版.代号Gingerbread(姜饼)
Android3.2版,代号Honeycomb(蜂巢)
Android4.0版,代号IceCreamSandwich(冰激凌三明治)
Android4.2版,代号JELLY BEAN

1.5版是第一个装机的版本
2.3版本是装机量最大的版本
3.0版本是第一个平板专用的版本
4.0版本开始平板手机共用的版本
我们现在主要的开发版本是基于4.0

Android的环境配置:
Eclipse3.5以上
MyEclipse

ADT是Eclipse开发Android的插件
https://dl-ssl.google.com/android/eclipse
通过以上地址,在MyEclipse中更新成最新版(如果将来又有更新,你需要先卸载以前
安装的,然后再重新下载最新)
下载AndroidSKD,放在全英文的路径目录下(个人建议丢在某个盘的根目录)
在MyEclipse的window菜单的preferences的菜单项中选择Android,然后在右边的
SDKLocation中填写刚才下载的AndroidSDK目录根目录的地址,记得点击Apply

开发Android,编写第一个Android程序---HelloWorld

建立Android Application Project
填写Application Name
ProjectName
PackageName
其中PackageName必须包含子包(拥有二级包)

选择Minimum Required SDK
TargetSDK
Compile With
通常情况下TargetSDK和Compile With是一致的


我们基本上使用4.0或4.2
next的第二个界面直接再next
在现在呈现的界面中可以修改图标样式和大小
再next后是界面风格的选择,选择第一个BlackActivity(标准的Activity)
再再next的界面是Activity的相关配置

Activity是Android中的一种用于,通俗的理解就是界面
1个Activity是1个界面
如果说程序有4个界面,那么你就需要有4个Activity
Activity的英文本意是活动

ActivityName的命名遵守Java类的命名规则

LayoutName的命名必须全小写,其他遵守Java命名规则

------------------------
Android的工程目录:
src目录:存放源代码
但是在Android中源代码必须存放在src目录下的包中

gen目录
是开发工具自动维护的目录,通常情况下我们不要去修改里面的内容
gen目录中有一个关键文件叫:R.java
R.java是Android所有资源的索引文件
任何在res目录下的资源都会同步在R.java中生成一个对应的常量,使用res的资源都通
过R.java中生成的常量来访问
在xml中我们使用:@xxxx/xxx来得到res的资源
而java中我们使用:R.xxxx.xxx来得到

assets目录
是资产目录,用于存放Android程序运行所需的资源,比如视频,声音,图片,数据库
文件等等

bin目录
程序产生的apk文件在该目录中

libs目录
类库包,用于存放Android程序所需要的第三方jar文件

res目录
资源目录,用于存放Android程序运行所需的资源,比如图片,界面布局,常量,动画
文件等等

res/drawable目录
用于存放图片资源

res/layout目录
用于存放界面布局文件
在Android搭建界面有两种方式
1.通过xml制定(类似html写界面的概念)
2.通过代码制定
大部分时候我们是使用第1种,少数情况下会混合第2种

res/values目录
用于存放常量文件,比如strings.xml表示字符串常量,colors.xml表示颜色常量等等


AndroidManifest.xml是Android的资源清单和程序配置文件


@是引用符号
@string是引用value中的字符串常量
@color是引用value中的颜色常量
@drawable是引用图片
等等.....

在Android中单位有以下几种:
px,sp,dip,dp
px是传统意义上的像素单位
sp是scale-independent pixel(与比例无关的像素)
通常用于指定字体
dp是density-independent pixel(与密度无关的像素)
dip是dp的另一种写法

关于密度
密度是指1个像素单位内的dpi值
1dp固定为160dpi

低密度:120 L
中密度:160 M
高密度:240 H
超高密度:320 XH

假设屏幕为480*800的Nexus S
4寸屏(宽度2.04寸)
那么每px的密度是480/2.04=235dpi (宽)
而235接近240,所以被认为是高密度屏
指定宽度为100px,实际密度就是23500

而如果使用dp
100dp的密度会这样计算,由于这个屏是高密度,所以固定每dp的密度是240
那么100dp就是100*(240/160)=150像素,实际密度是35250

480的宽意味像素总数为480*235=112800
使用px占宽度的20%
使用dp占宽度的31%

同样的宽度放入到320*480的屏幕上,设备尺寸为3.2的HTC Hero(宽度1.77)
那么每px的密度是320/1.77=180dpi
接近160,认为是中密度设备
那么宽度为100px,实际密度就是18000
而100dp则是100*(160/160)=100像素,实际密度是18000
320的宽意味像素总数为320*180=57600
使用px作为单位的宽度占整个宽度的31%
而dp作为单位的宽度占31%

在Android中我们基本上只使用两种单位:
大小用dp或dip,随意
字体用sp

--------------------------------------------
创建Activity的流程
问题:为什么要创建Activity
回答:因为你的程序要有界面,界面就是Activity
Activity相当于是JFrame

1.建立一个Class文件
2.继承Activity
3.编写Activity配套的layout布局文件并关联
4.在AndroidManifest.xml中注册Activity(如果有需要还可以指定启动的Activity是哪
一个)
在application的标签内嵌套activity标签指定activity类的路径完成注册
如果要配置成默认启动的Activity,那么需要在activity的标签内再嵌套
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

在Android中所有的控件有两个属性是必须存在的:
android:layout_width
android:layout_height
取值可以是以dp为单位的任意正整数
也可以是内部提供的常量:
wrap_content 根据内容大小决定
fill_parent 根据父容器大小决定
match_parent 相当于fill_parent

Dalvik虚拟机
传统Java程序运行class文件
而Dalvik运行dex文件
dex文件是对class文件进行整合后生成的文件

另外java虚拟机无论运行多少个程序,只有一个虚拟机实例
而Dalvik会为每个程序启动一个单独的虚拟机,从而隔离每个程序

最关键的是java虚拟机是基于栈的
而Dalvik是基于寄存器
=================================================
DDMS
View

DDMS是Android的调试控制器
Devices 驱动器,显示当前DDMS连接的设备(模拟器,真机)
FileExplorer 文件浏览器,通过文件浏览器浏览设备中的存储内容(大部分时候是用于
操作模拟器)
LogCat 运行日志,也可以理解为是Android的控制台
Emulator Control 仿真控制台,主要是用于模拟器模拟拨打电话,发短信,定位


LogCat是我们随时随刻都会查看的信息框
这个里面详细记录了整个设备以及当前程序的运行过程
异常,我们自定义的输出都会在LogCat中显示

异常发生以后的建议处理方式:
1.深呼吸,然后打开金山词霸,同时淡定的调整下心态,默默的和自己说:太好了,这是上
天给我一次难得的累积经验的机会
2.查看异常类型是什么(就是那个XxxxxxxxException),必要的话使用金山词霸翻译
.然后根据中文含义回想代码中哪些地方可能会导致这种状况
3.如果还找不到,那么查看at,从第一个开始,依次向下寻找自己亲手编写的那个类,而那
个类后面所接的行号就是错误发生的地点
4.根据错误代码的上下内容解决错误

如果需要本人提供帮助,那么才准备好2个东西:
1.什么异常(用中文)
2.把错误所在的代码找出来
-------------------------
View
在Android中所有的视图(控件),都是View

android.view.ViewRoot$CalledFromWrongThreadException: Only the original
thread that created a view hierarchy can touch its views.

--------------------------------------------------------------------
View称为控件
在Android中有两类View:
1.View 可以理解为标准控件,比如按钮,文本等等
2.ViewGroup 可以理解容器控件,比如布局,比如List等等

在Android中有5种布局,和Swing不一样,在Android中是强烈要求使用布局来进行控件的
摆放,因为Android设备不统一,各种分辨率和大小的屏幕都有
1.LinearLayout 线性布局,类似Swing的流布局
2.FrameLayout 帧布局,类似Swing的卡片布局
3.RelativeLayout 相对布局,类似Swing的包布局
4.TableLayout 表格布局,类似Swing的网格布局
5.AbsoluteLayout 绝对布局,被遗弃的布局,甚至大部分书籍都懒得提它

LinearLayout
是本人使用的最多的布局,基本上90%都用该布局来解决问题
线性布局不会自动换行,超出的控件将不会显示

layout_weight是LinearLayout特有的属性,只有属于LinearLayout的控件才具备该数据
这个属性用于设置控件的权重(英文直译,实际意思是控制控件占用剩余空间的优先度)
需要注意的是:如果设置了权重属性,那么宽度指定任何值都没有效果,所以通常会指定
为0dp,另外该控件还会在最后的时候才会摆放上去
假如有3个控件,A指定为1,B也指定为1,C也指定为1
那么A占用的大小是
1/(1+1+1)*100
33%
那么B占用的大小是
1/(1+1+1)*100
33%

假设现在分别指定为1,2,3
那么A占用的大小是
1/(1+2+3)*100
16%
B占用的大小是
2/(1+2+3)*100
33%
C占用的大小是
3/(1+2+3)*100
50%


在Android中设计界面有两种方式:
1.代码编写
2.xml编写

在实际编写过程中建议使用xml的方式来进行界面设计,然后必要的时候搭配代码,不建
议完全使用代码来编写(完全使用代码编写的行为属于装X行为)

注意:xml文件名必须全小写

关于Intent
Android中的组件访问通过意图实现
意图理解为想法,你将你的想法告诉Android,Android帮你实现
通俗的理解就是你只需要创建Intent,然后把要的东西的类名给它,剩下的,什么创建对
象啊,初始化啊等等都不需要你去干预,由系统自行完成

FrameLayout
帧布局很少使用,但是用到的时候非常好用
大多时候用于搞一些类似ps的层效果,当然还有后期聊到的TabHost也会使用

RelativeLayout
相对布局有人特喜欢用,有人几乎没怎么用
我个人通常不用,因为大部分效果都可以靠LinearLayout来实现
但是特有的布局效果相对布局更简单

相对布局有三组属性用于帮助定位控件位置
相对其他控件,取值是相对控件的id
layout_toRightOf
layout_below
layout_toLeftOf
layout_above

相对其他控件的边线对齐,取值是相对控件的id
layout_alignBaseline
layout_alignLeft
layout_alignTop
layout_alignRight
layout_alignBottom

相对父容器的某个位置,取值是true/false
layout_centerInParent
layout_centerHorizontal
layout_centerVertical
layout_alignParentLeft
layout_alignParentTop
layout_alignParentRight
layout_alignParentBottom

TableLayout
表格布局
这个布局最大的特点就是其包含的控件无需设置高宽
stretchColumns属性用于拉伸指定的列,让整个一行的内容占满屏幕宽度
值是索引,这些索引是隐藏的,从0开始

------------------------------------------------
基本控件
TextView
EditText
Button
ImageButton
ImageView
RadioButton
CheckBox

TextView是文本控件,但是不接收用户输入,类似Swing的JLabel,但是功能更加强大:
允许部分html标签来制定格式
(font,p,br,a,img)
能自动匹配内容形成动作链接
能自定义内容的动作和样式
能插入图片

Android的控件的结构:
View
|
----------------------------------------
| | |
ViewGroup TextView ImageView
| | |
----------------- EditText,Buttn ImageButton
| |
Layout Adapter


建议补充的课外内容:反射


EditText,是TextView的子类,是输入控件
自动提示完成功能
控制输入内容
插入图片

layout_marginXxx 设置控件距离其他控件(父容器边框)的距离
paddingXxxx 设置控件内容距离控件边框的距离
layout_gravity 设置控件在父容器中对齐的方式
gravity 设置控件的内容在控件中对齐的方式


Button
ImageButton
RadioButton
CheckBox

ImageView
(矩阵)
旋转
缩放

多点触摸


Http协议(request,response)
JavaWeb(Tomcat,Servlet)

------------------------------------------------
适配器

所谓的容器控件是指控件中可以存放N个数据项
比较典型的有列表控件,下拉控件,画廊

对于这类控件的共同点就是数据项需要通过适配器在控件中显示
是典型MVC:
model 数据源,形式上可能是数组,也可能是集合
view 控件本身,比如ListView
control 适配器,充当数据和控件之间的桥梁,简单点说,数据以什么形式,样式显
示出来,由适配器决定

在Android中适配器有四种:
ArrayAdapter 用于单数据显示,比如自动完成的输入文本框的提示内容
SimpleAdapter 用于复杂数据显示
SimpleCursorAdapter 用于显示来自Cursor的数据
BaseAdapter 自定义适配器,个人基本上99%都使用自定义的形式

在Android常见的适配器控件:
ListView
Spinner
GridView
Gallery
-----------------------------------------------
WEB概念
web简单的认为就是基于互联网的应用程序
通常客户端是浏览器

Http协议规范了互联网应用中请求方(客户端)和响应方(服务器)遵守的一种标准,格式
请求格式:


响应格式:

自己建立一个web应用,提供给Java的客户端使用(提交或是获取数据功能)
tomcat服务器软件的使用

首先确定一个小概念:服务器不是机器,而是软件
只是我们通常将安装了服务器软件的机器叫服务器
Tomcat是JAVA领域中使用面最广的服务器软件:
历史悠久
免费开源
安全
个性化
性能出众

安装过程一路next
需要注意如果没有自动或是错误的指定jre目录,那么就手动给它(jre或jdk都可以)

安装完毕后去到安装后的目录中找到bin目录
找到tomcat6w.exe文件,双击
将启动模式(startup type)更改为手动(Manual)
将服务设置为停止状态(Service Status更改为Stopped)

建立服务工程:
new-->web project

在javaweb程序中提供服务的文件被称为Servlet
Servlet本质上是一个Java类
和Swing一样,由于继承了某些东西,改变了自己的用途


第一个窗口指定好包名,类名,然后钩上doGet和doPost,其他的都去掉

第二个窗口中修改Servlet/JSP Mapping URL一项,这一项表示届时客户端的请求路径
,比如当前web程序名字叫hello,然后这个url被设置为world.html,那么客户端就需要
通过如下地址:
http://192.168.1.26:8080/hello/world.html
然后还需要注意的是不管改成什么,都需要/开头

http://192.168.43.64:8080/JSDX/hello_web.do
a3ffa85273ad
http://192.168.43.64:8080/00913Ajax/index.jsp
---------------------------------------------
Android的网络访问
访问的方式
传输纯文本内容
传输xml格式内容
传输json格式内容
传输图片,文件等格式内容(下载)

Android的网络访问有三种:
1.HttpClient
第三方提供的基于Http协议的网络访问API
已经被集成到Android中
2.3版本以前是推荐的连接和访问方式
但是2.3版本以后,这个第三方宣布不再更新和维护,所以后来的版本慢慢的不再使用,加
上下面那种连接方式的崛起,这种HttpClient的方式已经过时了

2.HttpURLConnection
这是Java本身提供的,和Android没关系
在2.3版本以后HttpClient的没落,以及自身的加强(比如提供了更多的支持,如压缩格式
等等),所以现在是推荐的Android网络访问方式

3.Socket
正常情况下基于HTTP的网络连接不会考虑这种方式,原因参考上周我们聊的

只有在非正常情况下:比如广告推送等这类需要持续连接的环境下才会使用Socket
其实现在QQ,微信也是用Socket来实现即时聊天的功能


关于XML和JSON
以上两种都是数据的一种存储方式
xml通过标签来组织和结构化数据
然后xml本身又是纯文本格式
所以xml被大量用在网络中进行数据的传输
也被大量应用在软件中作为系统参数和配置文件
比如我们要存放一个班级的学生:
<class>
<student name="张三" sex="男">
<subject name="语文" score="98"/>
<subject name="数学" score="89"/>
<subject name="外语" score="77"/>
</student>
<student name="李四" sex="女">
<subject name="语文" score="98"/>
<subject name="数学" score="89"/>
<subject name="外语" score="77"/>
</student>
<student name="王五" sex="男">
<subject name="语文" score="98"/>
<subject name="数学" score="89"/>
<subject name="外语" score="77"/>
</student>
</class>

json是最近几年出现的一个新玩艺
最开始是应用在Ajax技术中,在web页面和服务器交互数据时提高效率和操作性(以前
Ajax的数据传输是通过xml,大量的标签占用了流量,并且JavaScript解析xml也不是很人
性化)

比较典型的json格式:
{name="张三",sex="男",{name="语文",score=98,name="数学",score=89},name="李四
",sex="女",{name="语文",score=88,name="数学",score=77}}

java.net.SocketException: socket failed: EACCES (Permission denied)

android.os.NetworkOnMainThreadException

网络需要声明权限
<uses-permission android:name="android.permission.INTERNET"/>

在3.0版本之前网络操作可以在任意地方编写
而3.0后,Google为了防止网络操作导致界面被阻塞,所以要求网络操作必须在非UI线程
中处理

java.lang.RuntimeException: Can't create handler inside thread that has not
called Looper.prepare()

网络访问是个永恒的纠结问题,从未停止过
在Android中纠结更上一层楼:
一段代码,你要考虑哪些部分要放在非UI线程中处理,哪些部分要放在UI线程中处理
纠结的地方在这个考虑不是你愿意不愿意,性能好不好的问题,是不这么干就不行的问题
说白了,Android的线程无法避免的会涉及到一个线程和线程之间调度的问题

AsyncTask线程类可以完美的解决线程以及调度问题(谁用谁知道)
AsyncTask是Android自身提供的一个封装了线程的类
我们要做的就是new出来
然后实现doInBackground方法(这个方法是必须实现的)
AsyncTask通过其实例的execute方法启动任务
这个方法的参数类型由泛型的第一个参数决定
execute方法被调用后会自动调用doInBackground方法
将接收的参数同时传递给doInBackground方法

doInBackground方法顾名思义是后台方法,这个方法是个标准的线程方法,相当于Thread
的run方法,有自己的独立运行空间
doInBackground方法执行完毕后会调用onPostExecute方法
onPostExecute需要我们自己手动覆盖(这个方法的覆盖是可选的)
其参数就是doInBackground方法的返回值,这个类型由泛型的第三个参数决定
onPostExecute方法和doInBackground方法最大的不同点在于该方法是属于UI线程调度
的,也就是说在这个方法中可以进行任意的界面更新操作

xml可扩展标记语言
特点:文本形式(不受防火墙拦截),通过标签组织数据(可以传递复杂数据和结构数据),
可读性非常高(不需要借助第三方工具,人类可以直接阅读)

web程序中添加jar包的路径:
WebRoot/WEB-INF/lib目录

JSON
为什么叫JSON,其实我也不知道
但是JSON却是现在最炙手可热的数据传输解决方案
--------------------------------------
Gallery 画廊控件

数据在传输中永远都是以字节形式传递
byte
在形式上任何数据在传输的时候都是String格式


本周:
下载图片(多图片下载)
下载文件(对话框,进度条,通知栏,服务,SD卡)


Android中有以下几种消息的提示方式:
1.Toast
2.对话框
a.Activity模拟的对话框,这种对话框灵活度最高
b.标准对话框,用于显示信息,最多只提供三个按钮
c.带进度条的对话框(除此之外其实还有带时间或日期的对话框)
d.自定义对话框,只支持有限的几个控件,灵活度没有Activity模拟的对话框好,但是
基本上大部分时候我们都是使用自定义对话框而非Activity模拟的对话框,原因后面提
到Activity的生命周期时细聊
3.通知

服务
通知

下周预告:
利用服务+通知解决文件下载
Activity的生命周期初探


服务Service和Activity一样属于Android的组件之一
Android有四大组件:
服务 Service
活动 Activity
广播 Broadcast
内容提供者 ContentProvide
任何Android应用程序必定由以上1-4种组件组成

Service是一个看不见的Activity,不能和用户进行交互,在后台运行自己的程序

通知栏由于每次更新数据之后都要重新发布,所以如果过于频繁的更新通知栏数据会导
致系统反映缓慢(甚至进入假死状态)

Activity,或者说Android的系统和我们windows系统有个非常大的差别:
在我们使用电脑的时候总有一种习惯:
如果什么程序不用了,那么我们就要关闭它,甚至于在任务管理器中强制结束,简单的说
就是对于windows的程序我们如果不用了,就恨不得把这个程序销毁的干干净净,如果有
一点残余,那么各种不爽

但是在Android恰恰相反
如果你结束了一个程序(包括在设置->应用程序中结束),事实上这个程序其实还可能活

这样的处理带来的好处就是下次启动的时候启动速度会有很大的提升

但是你不能指望Activity结束后,其未完成的任务会肯定完成,因为虽然结束Activity,
而系统并未释放其内存,其任务会继续进行,但是在继续进行的过程中随时有被系统kill
的可能性,所以如果指望Activity结束后会继续完成其任务是不可靠的

最可靠的做法就是将需要Activity结束后(或者不依赖Activity)运行的任务放置到
Service中

Service是专门用于进行后台任务处理

Service有以下五个方法:
onCreate
onDestroy
onStart
onBind
onUnbind
以上五个方法构成了服务的生命周期,在某个特定的时候会调用其中某个方法

当通过startService方法启动服务的时候:
onCreate->onStart
如果再次启动服务,只会调用onStart
说明服务永远只存在一个实例
结束服务的时候会调用onDestroy

当通过bindService方法绑定服务的时候:
onCreate->onBind
当再次绑定的时候,什么都不执行
也就是说服务同一时间只能绑定一次
当绑定的Activity被结束或者调用unbindService会让服务解除绑定关系

服务通常都是用startService来启动,以便执行长时间的后台任务
在执行过程中如果想获得执行的进度等信息,那么可以通过bindService来在某个监控用
的Activity上绑定该服务

今天:
通知栏的使用
服务的生命周期以及绑定服务的概念

明天:
推送的实现(广告)
Activity的生命周期
------------------------------------------------
推送
服务器向设备发送信息

之前我们都是由设备向服务器发送请求,然后服务器才响应内容给我们的设备
但是很多时候我们需要服务器主动发数据给我们,这种情况叫推送

HttpURLConnection是基于HTTP请求的连接方式
Http协议有个特点,它是请求响应模式,每一次请求会得到一个响应,然后连接中断
新的请求会有新的连接

而推送则需要保持手机和服务器一直持续连接,因为只有这样服务器才能向手机主动发
送信息
持续保持
手机1------------|
手机2------------|-->服务器
手机3------------|
需要的时候向手机发送信息


保持持续连接使用Socket套接字

将接收写入到服务中,在后台运行
然后开机的时候自动启动(开机广播)

广播也是Android的组件之一
在Android中各种系统服务,硬件的状态变化都会发出一些信息给外界,我们称这些信息
为广播
之所以叫广播,是因为这些信息可以选择性的接收或者忽视

当手机启动的时候,会发出一条启动的广播信息
我们的程序要做的就是收听这条信息,然后开启推送的服务

intent-filter是意图过滤器
其功能是,你给他一段字符串常量
然后他会去根据这个字符串常量寻找对应的Activity或广播
这个字符串常量是Activity或广播的别名


开机广播在4.0后续的版本中做了个小修改:
必须要用户手动运行一次包含开机广播的程序,开机广播才生效

注意开机广播需要:android.permission.RECEIVE_BOOT_COMPLETED权限

Activity的生命周期由7个方法构成:
onCreate *****
onStart
onResume *****
onRestart
onPause *****
onStop
onDestroy

onResume和onPause是程序的边界
当执行onResume的时候说明程序界面即将和用户见面
当执行onPause的时候说明程序界面此时无法和用户进行交互
所以我们事实上认为这2个方法才是程序的边界

而onStop,onDestroy基本上都是属于忽略的方法,因为这2个方法并非100%一定会被调用

onCreate在一个程序的生命周期中只会调用一次,所以它特别适合进行界面元素的构成,
类似Swing程序的构造方法
但是对于界面元素的数据填充,则建议在onResume中,因为手机设备的特性会导致界面经
常会被覆盖掉(比如突然来了一个电话),而onResume可以保证它是界面显示在用户面前
之前最一个必定会调用的方法

本周:服务,推送的机制理解,编写个简单广播(开机)
----------------
周2晚3317
周3上午1,2 3320
周3晚上 3317

下周预告:
Activity的生命周期一定要搞定
广播的使用(拦截短信)
AIDL服务的写法(和自动挂断来电有关)
存储

剩下的部分还有:
多媒体
动画
传感器
GPS和GoogleMap服务

1 Activity杂七杂八,意图过滤器
2 广播(广播接收,广播发送)
3 广播的代码注册,AIDL服务,自动挂断来电
4 SharedPreferences
5 SQLite
6 ContentProvide
7 文件处理(SD的文件处理,内部的文件处理,Assets,res/raw)
8 POST提交数据至服务器
9 滑屏,TabHost,菜单,抽屉

课程设计阶段补充
多媒体
动画
传感器
GPS和GoogleMap服务
-----------------------------------------
Activity:
生命周期
状态保存(横竖屏切换)

Activity之间的值传递

广播接收,拦截处理短信广播
意图过滤器

Activity生命周期分为:
完整生命周期(Activity创建到销毁)
onCreate----onDestroy
可视生命周期(Activity可见到不可见)
onStart----onStop
前台生命周期(Activity可操作到不可操作)
onResume---onPause

正常情况下启动一个Activity会经历以下方法:
onCreate-->onStart-->onResume
当按back结束的时候:
onPause-->onStop-->onDestroy

如果是其他Activity覆盖了当前的Activity
比如来了电话,那么电话界面会强制覆盖当前的Activity
或者当按下Home键的时候
那么:
onPause-->onStop
如果在一段时间之内重新返回到这个Activity
那么:
onRestart-->onStart-->onResume

onDestroy是不靠谱的,所以千万不要将onDestroy作为程序的边界
那么程序边界设置为onStop可以么?

在传统程序中,比如桌面程序(Swing),web程序(JSP/Servlet)中,对话框是同步的
就是对话框出现后,会导致后续代码停止运行,等待对话框关闭后才继续执行
而Android中的对话框是异步的
简单的说:Android的对话框show出来后,后面的代码继续执行

如果在Android中要实现同步对话框,请选择Activity模拟

onPause是当前Activity失去用户操作时最后一个肯定会被调用的方法,而后面的
onStop以及onDestroy则不一定会触发
所以onPause是实际意义上程序的边界

而启动Activity最后的一个步骤是调用onResume


Android的横竖屏切换比我们想像中要复杂的多
它的切换是依靠摧毁,重新创建来实现
所以当切换横竖屏的时候会经历以下方法:
onPause-->onStop-->onDestroy-->onCreate-->onStart-->onResume
那么在这个过程中,程序的运行数据和状态会因为onDestroy的调用丢失,也会因为
onCreate的调用而重置
所以Activity还提供了2个专门解决这个问题的方法:
onSaveInstanceState
onRestoreInstanceState
调用的流程是:当切换横竖屏的时候
onPause-->onSaveInstanceState-->onStop-->onDestroy-->onCreate-->onStart--
>onRestoreInstanceState-->onResume

Activity之间的值传递
1.Intent传递
2.静态变量传递
3.全局对象传递
4.带返回的Activity返回处理结果

广播:
常见的系统广播:
开机广播
唤醒和休眠广播
短信到达广播
电话呼入和呼出广播
电量广播
..........

短信到达广播

13908498187

意图过滤器
发送广播
广播的代码注册
AIDL服务
自动挂断来电

意图过滤器Intent-Filter

Intent-Filter你可以理解为是一个索引,比如有个Activity叫M1,那么如果要启动这个
Activity,我们会通过以下代码:
Intent intent=new Intent(this,M1.class);
当然还可以使用另外一种方式(利用意图过滤器)
在注册M1这个Activity的时候,为其配置一个意图过滤器,指定Action为hello
那么需要启动M1的时候,那么可以这么写:
Intent intent=new Intent("hello");

意图过滤器对于Activity来说最大的价值有2个:
1.可以跨应用调用Activity
2.可以将多个Activity归类为一组,在使用的时候再由用户决定用哪个Activity来完成
操作

广播:
电话状态的监控
电话是一个很敏感且很重要的手机功能
所以Google在对待电话功能上是慎重的
在Android的API中没有提供对电话内容录音和操作的任何功能
而电话广播仅仅只能让我们接收到电话的三种状态:
响铃,接,挂

AIDL服务
远程服务调用
传统的Service服务只能被当前应用启动和绑定,如果需要被其他应用使用,那么就需
要AIDL服务

AIDL
Android Interface Declaration Language

实现步骤:
1.定义aidl文件(定义完成后,会自动生成对应的java类文件)
2.创建实现类(为了实现aidl文件中声明的方法实现),继承对应生成的java类中的内部
类Stub
3.注册,配置一个意图过滤,起一个别名
4.将生成的java类copy到客户端程序中(谁要去调这个服务,java类的文件就复制到谁
下面)
5.客户端程序绑定AIDL服务
IBinder需要通过
Xxxx.Stub.asInterface方法来转化,而非强制转型
Xxxx是生成的那个Java类名称

Service也被称为本地服务,只能被拥有这个Service的程序来访问和操作
AIDL的目的就是实现本地服务远程化,简单的说就是允许其他的程序来访问和操作不属
于自己的Service

挂电话:
正常情况下无法挂断,只能通过非常手段:
TelephonyManager类是电话管理类,它掌控着电话的一切行为
在这个类中有个方法叫getITelephony,这个方法会返回一个ITelephony对象,而
ITelephony对象实际是一个AIDL服务对象,它包含着控制电话的各种方法,其中就有
endCall挂断方法
(问:为什么会是一个AIDL?答:因为电话是一个公共功能,其功能要求能被其他的程序访
问到,所以就定义为了AIDL,而非普通服务.问:那为什么是服务,而不是其他的?答:这个
问题太白痴,想想,Android中什么东西能一直在后台运行,那只有服务)


自定义广播的实现
自定义广播可以让不同的程序之间相互通信

广播的注册方式:
广播有两种注册方式,一种是xml注册,一种是代码注册

xml注册是全局的,通过该方式注册的广播会一直生效,直到程序被卸载
而代码的仅仅在程序正在运行的时候才有效果

屏幕的休眠和唤醒(代码注册的问题)


任何程序都需要和数据打交道,而数据则需要存储:
在Android中,数据有四种存储方式:
1.文件存储
a.SD卡
b.内部文件(外部不可访问)
c.res/raw目录下的文件
d.assets目录下的文件
2.SharedPreferences
是一种轻量级的存储策略,适合存储配置信息,类似windows平台中的inf文件
3.SQLite
是一种轻量级的移动数据库,IOS也是使用SQLite
4.云储存
说白了就是数据不存放到手机本身,而是放到远程的服务器里


SQLite是一个移动设备的专用数据库
它的内存占用非常少,只需要几百kb
它的性能非常高,Oracle的速度比SQLite慢几十倍
它已经内置在系统中(Android,IOS等系统),所以无须额外安装任何软件
它的操作非常简单,看上去和操作文件差不多

SharedPreferences
适合存放小量数据

1.代码操作,不含界面
2.界面打包一起


程序需要保存一些配置信息:
音量大小
屏幕亮度
字体
用户名
密码

1.文件
缺点:
Vxxx=78
Sxxxx=100
fontxxx=xxxx
fontsize=18

2.数据库
缺点;
太夸张
---------------------------------------
文件存储
在Android中文件(IO流)可以存放到4个地方:
1.SD卡 这是最推荐的方式,因为SD卡的容量是最大的
2.应用程序内部 这种方式存放的文件无法被外界获取,只能通过当前应用程序取得
3.res/raw目录下 这个目录下存放的文件会随程序一起走(会打包到安装程序中,apk)
4.assets目录,这个目录下存放的文件会随程序一起走(会打包到安装程序中,apk)

应用程序被安装到设备中后,会在设备的内置内存的data/data/目录下建立一个同包名
的目录,然后所有和当前应用程序有关的数据默认都会存放到这个以包名命名的目录中
正常情况下,data/data是无法访问的,它受权限保护
除非你的设备被root了

res目录被称为资源目录,所有Android的资源都存放到这个目录下,比如布局,控件,颜色
,图片等等
并且所有的资源都会在R.java文件中形成对应的ID索引
不过res目录下的内容在被打包成apk的时候,所有的资源会被转译为二进制格式
但是res目录下的raw目录中的内容不会被编译为二进制格式

assets目录被称为资产目录
如果说res资源目录下的所有资源都会在R.java文件中生成对应的ID
那么assets资产目录下的所有资源不会有对应的ID,那么就意味着操作这些资源只能通
过流操作
assets目录下的所有文件都会原封不动的打包到apk中

res目录下的子目录命名是有隐式规则的,比如你可以命名一个子目录叫raw,但是不能命
名为rew,rsw,raw1
而raw目录下不允许再出现子目录
所以大量的,需要分类存放的资源并不适合存放到raw目录中

而assets目录完全由流操作,其本质就是个普通目录,你想怎么干都可以
---------------------------------------
SQLite数据库文件被创建后,如何打包到apk中和安装程序一起走
问题:创建SQLite数据库通常不会采用代码创建方式,而是提前通过第三方可视化管理工
具来生成
但是生成的这个SQLite数据库文件如何安放到客户机上是个大问题


解决办法:
将SQLite数据库文件放入到工程的assets目录中
在安装后,第一次运行的时候扫描sd卡是否存在sqlite数据库文件,如果不存在读取
assets目录中的数据库文件通过流写入到sd卡中

问题:那为什么不直接操作assets目录中的数据库呢?
答:因为操作不了
-------------------------------------------------
ContentProvider
暴露数据供外界使用

在Android中数据默认都是私有的(data/data/包/...目录下)
意味着属于A程序的数据,永远不会被A程序之外的程序获取

如果需要将A程序的数据提供给其他程序使用,那么就需要使用到ContentProvider
大概的流程:

|----ContentReceiver ----B程序
A程序 |----ContentReceiver ----C程序
ContentProvider-----ContentReceiver ----D程序
约定一个暗号(Authoritiy)


一个标准的URL由三个部分组成:
1.scheme
2.authoritiy (域名)
3.path (资源)

        <p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>

标签: android

热门推荐