Android大致分为四层架构,应用层、应用框架层、系统运行库层、硬件抽象层、Linux内核层。
Android 的核心系统服务基于Linux 内核,在此基础上添加了部分Android专用的驱动。系统的安全性、内存管理、进程管理、网络协议栈和驱动模型等都依赖于该内核。
硬件抽象层是位于操作系统内核与硬件电路之间的接口层。
其目的在于将硬件抽象化,为了保护硬件厂商的知识产权,它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。
从软硬件测试的角度来看,软硬件的测试工作都可分别基于硬件抽象层来完成,使得软硬件测试工作的并行进行成为可能。通俗来讲,就是将控制硬件的动作放在硬件抽象层中。
Android运行时库
运行时库又分为核心库和ART(5.0系统之后,Dalvik虚拟机被ART取代)。核心库提供了Java语言核心库的大多数功能。
Dalvik被ART取代的原因是,ART可以直接将java文件编译成机器码运行,而Dalvik则需要将java文件先编译成.class文件,再解释.class文件成机器码运行,相比之下Dalvik下运行的apk速度就会慢很多。
应用框架层为开发人员提供了可以开发应用程序所需要的API,我们平常开发应用程序都是调用的这一层所提供的API,当然也包括系统的应用。这一层的是由Java代码编写的,可以称为Java Framework。
在手机上的应用程序都属于这一层
从目录结构可以发现,packages目录存放着系统核心应用程序、第三方的应用程序和输入法等等,这些应用都是运行在系统应用层的,因此packages目录对应着系统的应用层。
系统运行库层(Native)中的 C/C++程序库的类型繁多,功能强大,C/C++程序库并不完全在一个目录中,这里给出几个常用且比较重要的C/C++程序库所在的目录位置。
Android系统的启动流程就是先后启动C,Java的各种服务,再返回启动Luncher即可进入用户交互的UI界面。
4.SystemServer.java中有两个方法init1()启动Native世界,init2()启动Framework世界
5.init2()方法启动ServerThread中的run方法,开启各种系统服务,然后调用ActivityManagerService.systemReady方法启动home界面
四大组件
活动是在应用中所有看得见的东西;
服务是在后台默默运行;
广播接收器,接收电话或者短信等,同样也可向外广播消息;
内容提供,在应用程序之间共享数据,如读取系统电话簿的信息。
丰富的系统控件
可以编写出漂亮的界面。
强大的多媒体
在开发的应用中用程序控制多媒体服务
SQLite数据库
轻量级、运算速度快的嵌入式关系型数据库,支持SQL语法,可以通过安卓封装好的API进行数据的增删改查。
地理位置定位
jdk是java语言软件开发工具包
Android SDK是Android开发工具包
Android Studio是开发Android项目的IDE工具
任何新建项目默认使用Android模式的项目结构,但这不是真实的项目结构。
放置Android Studio自动生成的文件
项目的代码、资源都放在这个目录下,平时的开发工作也在这里进行。
编译时自动生成的文件
包含gradle wrapper的配置文件
Android Studio默认没有启用gradle wrapper的方式,如果需要打开,可以点击File->Setting->Build,Execution,Deployment->Gradle进行配置更改。
将指定的文件或者目录排除在版本控制之外
项目全局的gradle构建脚本
全局的gradle配置文件,此文件匹配的属性会影响到项目中所有gradle编译的脚本。
在命令行界面执行gradle命令,其中gradlew是在linux或者Mac系统中使用,gradlew在windows系统中使用
iml文件是所有Intellij IDEA项目都会生成的一个文件
指定本机中的Android SDK路径。
指定项目中引入模块
此目录与外层的build目录相似,主要也是包含编译自动生成的文件。
放置jar包
编写AdroidTest测试用例,实现自动化测试。
放置java代码
项目中的图片、布局、字符串等都放置在此。
图片放在drawable目录下,布局放在layout目录下,字符串放在valuse目录下。
整个Android项目的配置文件,程序中定义的四大组件都要在这个目录下注册,可以在此给应用程序添加权限声明。
编写Unit Test测试用例
将app模块内指定的目录或者文件排除在版本控制之外。
Intellij IDEA项目自动生成的文件
APP模块的gradle构建脚本,指定项目构建相关配置。
指定项目代码的混淆规则,在代码开发完成之后打成安装包文件,让代码难以被他人破解。
android.intent.action.MAIN
打开AndroidManifest.xml文件,找到如下代码:
这段代码是对HelloWorldActivity活动的注册,没有再AndroidManifest.xml文件中注册的活动是不能使用的。
在手机上点击应用时,首先启动android.intent.action.MAIN
这个主活动。
HelloWorldActivity
在界面中看到的东西就是HelloWorldActivity这个活动中的东西。
Activity是Android系统提供的一个活动基类,项目中的所有活动都必须继承它或它的子类才拥有活动的特性。AppCompatActivity是Activity的子类。
onCreate()
方法是活动被创建时必须执行的方法。
hello_world_layout布局
在界面上看到的Hello World!字样不在HelloWorldActivity.java文件中,在哪?由于Android程序设计讲究逻辑和视图的分离,因此不是在活动中而是在布局中编写界面,在活动中引入。setContentView()
方法就给当前的活动引入一个hello_world_layout布局。
当打开res/layout目录下,可见hello_world_layout.xml文件,Hello World!在此处定义,andorid : text = “Hello World!”
。
打开res目录
drawable开头的文件夹存放图片,存放不同分辨率的图片,适应不同设备的显示要求。
mipmap开头的文件夹存放应用图标,主要是为了让程序兼容各种设备。
values文件夹存放字符串。
layout文件夹存放布局文件。
这里定义一个应用程序的字符串
在代码中通过R.string.hello_world
获得该字符串引用;
在XML中通过@string/hello_world
可获得此字符串的引用。
基本语法即是以上两种方式,其中string是可以替换的,如果引用图片资源就替换成drawable,如果引用应用图标就替换成mipmap,如果引用的是布局文件就替换成layout。
首先两处文件的repositories的闭包都声明jcenter()
配置,他是一个代码托管仓库,许多Android开源项目都会选择将代码托管到jcenter上,声明这行配置之后可以引用任何jcenter上的开源项目。
由于gradle不只可构建Android项目,还可构建C++、java项目。则需要声明com.android.tools.build:gradle:2.2.0
来说明是构建Android项目。
com.android.appilcation
表示是一个应用程序块,可以直接运行。
com.android.library
表示一个库模块,只能作为代码依附于别的应用程序模块运行。
在下面一个大的android闭包中可以配置项目构建的各种属性。
compile fileTree
,表明libs目录下所有.jar文件都添加到项目的构建路径中。compile project
+依赖的库名,如compile project(':helper')
com.android.support:appcompat-v7:24.2.1
,其中com.android.support
是域名,appcompat-v7
是组名区分不同库,24.2.1是版本号Log.v()
打印最为琐碎,意义小的信息
Log.d()
打印调试信息
Log.i()
打印比较重要的信息
Log.()
打印警告信息
Log.e()
打印错误信息
以上每个方法的级别依次递增
Log.d()
中传入两个参数,第一个是tag,一般传入当前的类名。第二个参数是msg,想要打印的内容。
活动是包含用户界面的组件,用于与用户的交互。
创建一个项目,选择Add No Activity,手动创建活动,如下:
项目创建手动改成Project模式,在app/src/main/java/com.example.activitytest目录此时为空,右击com.example.activitytest包->New->Activity->Empty Activity,不要勾选Gnerate Layout File和Launcher Activity。
勾选Lanucher Activity表示自动将活动设置为项目主活动;勾选Generate Layout File自动为活动创建布局文件;勾选Backwards Compatibility表示为项目启用
在ContentProvider中需要获取特定的uri来得到对数据进行CRUD操作的Cursor。
Uri的getPathSegments()方法返回的是一个元素为String的List,每个元素都是从Uri截取出来的一部分。
第一个元素为第一个“/”右边的字符。
Uri uri = Uri.parse("content://com.haha.mycontentproviderdemo.NoteContentProvider/notes");
Uri myUri = Uri.withAppendedPath(CONTENT_URI, "#/2");
List list = myUri.getPathSegments();
int i = 0;
for (Iterator iterator = list.iterator(); iterator.hasNext();i++) {
String string = (String) iterator.next();
Log.i("test", "集合里的元素为:" + string);
Log.i("test", "集合中下标为 " + i +"的String类型元素为:"+ list.get(i));
}
在RecyclerView中自定义点击事件的接口,即可实现在Activity中直接注册adapter各个元素的点击事件,无需在onBindViewHolder()中注册点击事件。
在Adapter中定义点击事件的方法和接口
private AdapterView.OnItemClickListener mOnItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
在Activity类中注册使用此接口。
adapter.setOnItemClickListener(new ZoneTimeAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
String cityName = TimeZoneUtil.cityList.get(position);
Message msg = timeZoneBinder.transTime(cityName);
handler.sendMessage(msg);
}
});