Android【基础篇】
一 通信技术
1G: 通信标准:模拟制式 只能进行语音通话,不能发送短信
2G: 通信标准:数字制式:GSM和CDMA 收发短信和邮件
2.5G: 通信标准: GPRS,EDGE 访问wap网络数据(图片,壁纸,文字信息)
3G: 通信标准: WCDMA(联通),CDMA2000(电信),TD-SCDMA(移动) 发微博,上qq,查看高清图片,电影(看电影还不成熟)
3.5G: 通信标准: WCDMA延伸的技术:HSDPA,HSDPA+
4G: 通信标准: TD-LTE,由TD-SCDMA演变过来,现在已成为国际通信标准,下载速度:50Mb/s 上传速度:10Mb/s
【注意】 50Mb/s != 50 MB/s 。因为小写的b是bit,大写的B是byte,1byte=8bit,所以50Mb/s=6.25MB/s。
二 Android版本问题
1.5-2.3是手机版本,3.0-4.0是平板版本,之后的版本就不分手机和平板版本了。
”向上兼容“原则
兼容2.3.3就可以兼容以后的版本,但2.3.3之前的版本就需要单独配置了。
三 Android体系结构
2.1 体系结构图
Linux Kernel:Linux内核,可以说Android系统也是Linux系统,这一层存放的是硬件驱动,等等与硬件交互的一些程序,
Libraries:Android系统重要功能的函数库,比如3G绘图,2G绘图,SQLite数据库,浏览器内核,C语言标准库等等。因为在Linux Kernel中与硬件的交互程序大多数用C实现的。
application framework:应用框架层,安卓通过Manager来管理API,并把API暴露给程序员。
applications:开发的第三方应用。
模拟一次Android下调用顺序-闹钟程序
applications下有个闹钟应用,想要响应就要调用application framework的一些API,这些API实际调用Libraries的Media Framwork。然后Media Framwork实际就调用了Linux kernel中声卡的驱动。最终手机才开始“铃..铃..铃...”。
android Runtime:这层就有点类似于java中的jre,Core libraries实际就是改写了一些jre类库代码,Dalvik相当于jre中的虚拟机,java需要在运行在java虚拟机中,并要有jre提供的一些环境类库支持,才可以运行。那么安卓程序就要运行在Dalvik VM(安卓的虚拟机)中,并且需要core Libraries的支持。
2.2 Dalvik VM与Java VM的比较
JVM:首选要编译.java文件,当然编译不是由JVM做的,在编译的过程中,我们把编译好的多个.class文件打成了jar包,然后把jar包交给jvm执行,jvm这个进程,会划分在电脑中划分内存空间,并把这片内存空间类堆,栈。所以堆栈是JVM的架构。
DVM:首先要编译.java文件,这里DVM不能加载.class文件,要想执行,必须使用dx.bat命令把.class变为.dex文件。然后DVM就可以对.dex文件解释运行了,DVM架构是寄存器(CPU上的一个高速缓存),把重要的信息放在寄存器上。
流程对比:
jvm | .java -> javac -> .class -> jar -> .jar |
dvm | .java -> javac -> .class -> dx.bat -> .dex |
2.3 .jar文件与.dex文件的区别
三 Android开发环境搭建
下载SDK,并执行下载文件中的SDK Manager
3.1 下载前的一些设置
打开文件夹下的SDK Manager.exe。弹出一个
安卓的开发版本由google管理,google是国外网站,国内没有FQ的话无法访问,或者访问很慢。所以对SDK Manager做一些特殊处理,点击Tools下的option。勾选Others下的force https://....这个选项,意思就是把https的请求变为了http请求。
然后修改C:\Windows\System32\drivers\etc\下给hosts文件添加一些内容,该hosts文件相当于本地的DNS域名解析器。
74.125.113.121 developer.android.com
203.208.46.146 dl.google.com
203.208.46.146 dl-ssl.google.com
这样设置以后,就可以在中国去下载这些sdk了。
-------------------------懵逼分割线--------------------------------
本以为这样子SDK Manager就可以正常更新了,但是网路实在差到极点,搜索了半天,发现了一个极好的解决办法,就是东软提供给我们的网站镜像
这样子sdk manager就可以开始下载了
3.2 启动模拟器报错的问题
当模拟器路径出现中文或者空格的时候,会报错。此时我们需要配置一个名字为“ANDROID_SDK_HOME”,值为一个路径,这个路径就是创建虚拟机所在的路径,注意此时你自己指定的路径就不要出现中文和空格了。
四 DDMS与adb
4.1 什么是adb?
在sdk/plateform-tools下有一个名为adb的可执行程序,全名为android debug bridge,译为安卓调试桥,用来管理模拟器或真机状态的万能工具,该工具采用了客户端-服务器模型
客户端,运行在开发者电脑上,可以在dos环境下执行adb命令来调用客户端,adb插件,ddms工具都可以调用adb客户端
服务端,运行在开发者电脑的后台进程上,用来管理客户端与运行在模拟器,真机的守护进程 之间的通信。
守护进程运行在模拟器或真机的后台。
4.2 什么是DDMS?
在eclipse下面的一个工具,只要在ddms试图的device中显示了模拟器信息,说明eclipse与模拟器通过adb连接成功,如果模拟器启动,ddms试图的device试图没有显示模拟器信息,说明eclipse与模拟器没有连接。
ddms的logcat是android下的输出平台,好比之前我们syso的时候,输出到控制台,而现在当我们在安卓应用中打印syso,就会在logcat试图下输出
ddms的file explorer对应模拟器下的各个文件夹。
ddms的emulator control模拟与你创建模拟器的交互操作。
4.2 使用adb
前提:需要配置adb.exe的环境变量。
也就是把adb.exe命令所在的文件路径放入到系统环境变量path路径中,让我们可以在任何路径下使用adb命令,当调用了adb start-server启动adb客户端时,客户端首先检测adb服务器端进程是否运行,如果adb服务端没有运行,就启动服务端,当服务端启动后,就会绑定到本地的tcp 5037端口,并且监听从adb客户端发来的命令,所有的adb客户端都使用5038端口与adb服务端通信
接下来服务端与所有正在运行的模拟器或手机连接,通过扫描5555-5585之间的奇数号端口来搜索模拟器或手机,一旦发现adb守护进程,就通过此端口进行连接,需要说明的是,每一个模拟器或手机使用一对有序的端口,偶数号端口用于控制台连接,奇数号端口用于adb连接。
Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557 ...
当服务端与所有的模拟器建立连接之后,就可以使用adb命令来控制或访问了,因为服务端管理着连接,并且接受到多个adb客户端的命令,所以可以从任何一个客户端脚本来控制任何模拟器或手机设备,
adb devices:列出所有设备,注意后面不要输入";"
adb start-server:开启adb服务
adb kill-server:关闭adb服务
adb logcat:查看log
adb shell:进入手机根目录,进入到了linux空间,其中“#”代表超级用户权限,输入linux命令"ls"。就可以看到手机根目录了。
adb install 路径:安装一个apk程序。
adb uninstall 程序的报名:Android系统下在手机里的包名都不相同,那么是不是名字相同安装就覆盖了,实际上还要判断签名文件是否相同,如果包名相同的情况下签名文件也相同,那么就会发生覆盖
adb pull:存文件,后面紧跟"文件全称 模拟器存放路径“
adb push:取文件,后面紧跟”模拟器存放路径 要放到的路径“
【注意】如果你开启了多个虚拟机,你就需要在adb后面加上"-s 模拟器名称"
emulator -avd<模拟器名称>:启动模拟器,记得要配置环境变量,该命令在SDK的tools文件下。
五 创建第一个安卓程序
第一步:
第二步
New Android Application,创建图表,创建activity,指定workspace
第三步
自定义一些图表
第四步
Activity Name指的是界面的名称
Layout Name指的是布局的名称,这是默认的布局
第五步
创建完成,工程结构如下图所示
第六步:
右键Run As->Android Application,就可以运行了。
错误一
可以,但是,实际动作果然问题百出,所以运行以后在模拟器看到了我们的应用,但是点击应用出现了一个错误
按理说我按照教程一步不差的输入,为什么报了这个问题,最终和成功的项目对比,改动了两处,第一处是src目录下自动创建的com.example.myfirstapp.MyActivity下的类继承了一个过时的方法,原本是以下这样
public class MyActivity extends ActionBarActivity { ... } //ActionBarActivity是一个过时方法
我们将其改为
public class MyActivity extends Activity { ... } //android.app.Activity
第二处是bin目录下的AndroidManifest.xml文件,将其中一个属性改为我们在创建时候自定义的一个名称
android:name=".MyActivity" //原本是默认值,现在改为我创建时自定义的名字
错误二:
Call requires API level 11 (current min is 10): android.app.Activity#onCreateView
【总结】
这时候run as,android application就可以看到模拟器显示了helloworld页面,至于为什么修改了几处地方就可以成功,我们后续就要重点关注那两个地方在android程序中,扮演了什么地位
六 安卓工程目录结构
src:存放源代码
gen:自动生成的文件
R.java:对应着resource首字母,resource中的一个图片,对应R文件一个int类型的值,改值就是图片的地址值。这样做是站内用空间小,当放在寄存器的时候,效率高,当你修改resouce中的东西时,R对应自动修改。所以R就是映射resource文件
Android x.x.x:就是当前application所使用的开发工具包版本,可以更换版本,更换方式一:右键,选择properties修改。更换方式二:修改安卓目录下的project.properties,来更换版本
Android Private Libaries:工程所依赖的jar包,以及函数库。如同javaweb中在lib下的jar包会自动build path到application中。在android中我们放过如libs下的jar包会自动builpath到application中。
assets:放置程序所依赖的音频文件,数据库,一些资源文件,与resource不同的是,当你放入assets后,不会再R.java自动生成变量。而放在resource中的资源会自动生成到gen/R.java中。
bin:工程的编译目录,存放编译时产生的临时文件和当前工程的.apk文件
res:全称resource,就是资源文件
drawable:存放程序所用的图片,针对不同的屏幕大小,不同的分辨率存放的图片
layout:存放android的布局文件
展示页面,点开其中的.xml文件,可以更改和预览布局。layout与activity的关联也是通过R.java
menu:存放android的OptionMenu布局
values:程序所需要的数据,会在R文件自动生成代码
string.xml:存放安卓字符串
dimens.xml:存放屏幕适配所使用的尺寸
style.xml:存放安卓下显示的样式
values-xxxx:针对不同尺寸的设备一些数据
values-v11:指定3.0版本以上手机显示的样式
AndroidManifest:android应用程序的入口文件。声明了Android里边的组件和相关配置信息
proguard-project.txt:加密当前程序所使用
七 打包安装过程
我们知道,当我们点击了Run as->Android Application,就会开启一个模拟器,然后启动了应用,显示了一个activity。那么从我们点击run的时候,eclipse到底都做了什么工作呢?
看console下生成的信息
[2016-02-26 18:23:26 - 第一个app] ------------------------------
[2016-02-26 18:23:26 - 第一个app] Android Launch!
[2016-02-26 18:23:26 - 第一个app] adb is running normally.
[2016-02-26 18:23:26 - 第一个app] Performing com.example.firstapp.MainActivity activity launch
[2016-02-26 18:23:26 - 第一个app] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'firstapp_intel'
[2016-02-26 18:23:26 - 第一个app] Uploading 第一个app.apk onto device 'emulator-5554'
[2016-02-26 18:23:32 - 第一个app] Installing 第一个app.apk...
[2016-02-26 18:23:34 - 第一个app] Success!
[2016-02-26 18:23:34 - 第一个app] Starting activity com.example.firstapp.MainActivity on device emulator-5554
[2016-02-26 18:23:34 - 第一个app] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.firstapp/.MainActivity }
1.启动adb客户端,帮助我们管理虚拟机
2.执行启动我们的MainActivity页面,之所以是这个页面,是因为AndroidManifest是应用程序的人口文件,会首先执行该文件中包含以下标签的activity
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
3.自动选中一个模拟器
4.加载apk文件到模拟器中
在此期间,加载apk文件之前,就要先生成apk文件,apk文件就是一个压缩包,其中包括:
(1).dex文件(所有的.class文件)
(2)resources.arsc(资源索引表)
1,把xml文件从文本格式变成2进制格式
2,生成资源索引表resources.arsc
3,把resources.arsc转换成二进制格式
(3)uncompiled resources(未编译的资源文件)
放在android application的assets和一些不要编译的图标
(4)AndroidManifest.xml,应用程序入口文件转换后的二进制文件
在生成.apk文件后,还要对apk文件进行签名,使用"C:\Users\dyp\.android\debug.keystore"进行签名,之后通过adb就可以操作模拟器,来进行安装了,我们把apk文件加载到了模拟器的/data/local/tmp/xxx.apk。
5.安装
我们在使用adb install命令的时候,把apk文件加载到了/data/local/tmp下,而安装是要把apk文件剪切到/data/app中,名字为"包名-1.apk"。在/data/data文件夹下创建一个名为包名的文件,来存放当前程序产生的数据,在/data/system/packages.xml和/data/system/packages.list文件中分别添加一条记录,通过包名关联了/data/app与/data/data下的文件。
八 拨号器的布局
一。创建Android project
二。自定义布局
修改/res/layout下的xml文件
<!-- 文本框 --> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/title"/> <!-- 输入框 --> <EditText android:id="@+id/number" android:layout_below="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number"/> <!-- 按钮 --> <Button android:layout_below="@+id/number" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/callNumber" android:onClick="call"/>
三。在Activity中写响应函数
/** * 当布局中的按钮被点击时,触发该方法 * @param v */ public void call(View v){ System.out.println("拨打电话"); // 第一步,取出控件中的号码 EditText editText=(EditText) findViewById(R.id.number); String number=editText.getText().toString(); // 第二步,根据号码拨打电话 Intent intents=new Intent();//创建意图 intents.setAction(Intent.ACTION_CALL);//指定动作为拨打电话 intents.setData(Uri.parse("tel:"+number));//指定要播出的号码 startActivity(intents);//执行这个动作 }
四。获取权限,
在AndroidManifest.xml文件下增加打电话的权限
<!-- 添加拨打电话的权限 --> <uses-permission android:name="android.permission.CALL_PHONE"/>
九 四种点击事件
第一种:在根目录/res/layout/activity_my.xml中,给buttion标签增加监听事件
<Button ...... android:onClick="call"/>
剩下的三种,都是给buttion增加一个id属性,然后在oncreate方法,获取buttion,然后增加onclick事件监听器。不同的是参数的不同。
第二种,匿名内部类
/** * 当页面刚创建的时候,回调次方法。 */ protected void onCreate(Bundle savedInstanceState) { //执行父类初始化操作 super.onCreate(savedInstanceState); //更改布局 setContentView(R.layout.activity_my); Button button=(Button) findViewById(R.id.btn_call); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub System.out.println("2 拨打电话"); call(); } }); }
第三种,内部类
/** * 当页面刚创建的时候,回调次方法。 */ protected void onCreate(Bundle savedInstanceState) { //执行父类初始化操作 super.onCreate(savedInstanceState); //更改布局 setContentView(R.layout.activity_my); Button button=(Button) findViewById(R.id.btn_call); button.setOnClickListener(new clickListener()); } class clickListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub System.out.println("call"); } }
第四种,使用this
public class MyActivity2 extends Activity implements OnClickListener{ /** * 当页面刚创建的时候,回调次方法。 */ protected void onCreate(Bundle savedInstanceState) { //执行父类初始化操作 super.onCreate(savedInstanceState); //更改布局 setContentView(R.layout.activity_my); Button button=(Button) findViewById(R.id.btn_call); button.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub call(); }