Android简介
1.手机操作系统
在早期的手机内部是没有智能操作系统的,所有的软件都是由手机生产商在设计时所定制的,因此手机在设计完成后基本是没有扩展功能的。后期的手机为了提高手机的可扩展性,使用了专为移动设备开发的操作系统,使用者可以根据需要安装不同类型的软件。操作系统对于手机的硬件配置要求较高,所产生的硬件成本和操作系统成本使手机的售价明显高于不使用操作系统的手机。
手机上的主要操作系统:Android,IOS,Windows Phone 8,黑莓,Linux。
2.Android起源
开放手机联盟(Open Handset Alliance,OHA)由谷歌公司于2007年发起的一个全球性的联盟组织,成立时包含34家联盟成员,现在已经增加到82家。
2007年11月12日,谷歌发布Android SDK预览版 ,这是第一个对外公布的Android SDK,为发布正式版收集用户反馈。
2008年4月17日,谷歌举办总共1000万美金的Android开发者竞赛,奖励最有创意的Android程序开发者:cab4me(出租车呼叫)、BioWallet(生物特征识别)和CompareEverywhere(实时商品查询)。
2008年8月28日,谷歌开通Android Market,供Android手机下载需要使用的应用程序。
2008年9月23日,发布Android SDK v1.0版,这是第一个稳定的SDK版本。
2008年10月21日,谷歌公布Android平台的源代码。
3.Android的特征
在内存和进程管理方面,Android具有自己的运行时和虚拟机:
(1)Android为了保证高优先级进程运行和正在与用户交互进程的响应速度,允许停止或终止正在运行的低优先级进程,以释放被占用的系统资源。
(2)Android进程的优先级并不是固定的,而是根据进程是否在前台或是否与用户交互而不断变化的。
(3)Android为组件定义了生命周期,并统一进行管理和控制。
在界面设计上,提供了丰富的界面控件:
(1)加快了用户界面的开发速度,保证了Android平台上的程序界面的一致性。
(2)Android将界面设计与程序逻辑分离,使用XML文件对界面布局进行描述,有利于界面的修改和维护。
Android提供轻量级的进程间通讯机制Intent,使用跨进程组件通信和发送系统级广播成为可能。
Android支持高效、快速的数据存储方式:
SharedPreferences、
文件存储
轻量级关系数据库SQLite
Android体系结构
1、Linux内核
2、中间件层
3、程序框架层
4、应用程序层
Linux内核:
(1)硬件和其他软件堆层之间的一个抽象隔离层。
(2)提供安全机制,内存管理,进程管理,网络协议堆栈和驱动程序。
中间件层:
(1)由函数库和Android运行时构成。
(2)Android运行时,核心库,提供Android系统的特有函数功能和Java语言函数功能。
(3)ART虚拟机,采用预编译技术,在应用程序安装时把程序代码转换成机器语言,加快了启动速度,并且使用应用程序的运行速度更快、电量消耗更少,系统也更加流畅。
应用程序框架层:
(1)提供Android平台基本的管理功能和组件重用机制。
应用程序层:
(1)提供一系列的核心应用程序。
(2)包括电子邮件客户端,浏览器,通讯录和日历等。
Android程序结构
子目录,库和工程文件
(1)根目录下包含5个子目录src、gen、assets、bin和res。
(2)2个库文件android.jar、android-support-v4.jar。
(3)3个工程文件Androidmanifest.xml、project.properties和proguard.cfg。
src目录是源代码目录,所有允许用户修改的java文件和用户自己添加的java文件都保存在这个目录中 。
gen目录用来保存ADT自动生成的java文件。
assets目录用来存放原始格式的文件。
bin目录保存了编译过程中的所产生的文件,以及最终生产的apk文件。
res目录是资源目录,Android程序所有的图像、颜色、风格、主题、界面布局和字符串等资源都保存在其下的几个子目录中。
(1)其中,drawable-hdpi、drawable-mdpi和drawable-ldpi目录用来保存同一个程序中针对不同屏幕尺寸需要显示的不同大小的图像文件。
(2)layout目录用来保存与用户界面相关的布局文件。
(3)values目录保存颜色、风格、主题和字符串等资源。
activity_main.xml文件:
activity_main.xml文件是界面布局文件,利用XML语言描述的用户界面
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="edu.hrbeu.helloandroid.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
Android组件
Activity组件
Android程序的呈现层,显示可视化的用户界面,并接受与用户交互所产生的界面事件。
Android应用程序可以包含一个或多个Activity,一般需要指定一个程序启动时显示的Activity。
Service组件
Service一般用于没有用户界面,但需要长时间在后台运行的应用。
可公开Service的程序接口,供其他进程调用。
BroadcastReceiver
用来接收广播消息的组件,不包含任何用户界面。
可以启动Activity或者Notification通知用户接收到重要信息。
ContentProvider
是Android系统提供的一种标准的共享数据的机制,其他程序通过ContentProvider访问程序的私有数据 。
Android系统内部提供一些内置的ContentProvider,能够为应用程序提供重要的数据信息。
程序生命周期
前台进程是Android系统中最重要的进程。
可见进程指部分程序界面能够被用户看见,却不在前台与用户交互,不响应界面事件的进程。
如果一个进程包含Service,且这个Service正在被用户可见的Activity调用,此进程同样被视为可见进程。
服务进程包含已启动服务的进程,Android系统除非不能保证前台进程或可视进程所必要的资源,否则不强行清除服务进程。
后台进程指不包含任何已经启动的服务,而且没有任何用户可见的Activity的进程,Android系统中一般存在数量较多的后台进程。
空进程是不包含任何活跃组件的进程。
程序生命周期
进程的优先级取决于所有组件中的优先级最高的部分。
进程的优先级会根据与其他进程的依赖关系而变化。
组件生命周期
所有Android组件都具有自己的生命周期,是从组件建立到组件销毁的整个过程。
在生命周期中,组件会在可见、不可见、活动、非活动等状态中不断变化。
Activity生命周期
Activity生命周期指Activity从启动到销毁的过程。
Activity表现为四种状态:
(1)活动状态,Activity在用户界面中处于最上层,完全能被用户看到,能够与用户进行交互。
(2)暂停状态,Activity在界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互。
(3)停止状态,Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡。
(4)非活动状态,不在以上三种状态中的Activity则处于非活动状态。
Activity栈
遵循“后进先出”的规则:
随着Activity自身状态的变化,Android系统会调用不同的事件回调函数。
Activity生命周期的事件回调函数
Activity事件回调函数的调用顺序
Activity生命周期分类
Activity的生命周期可分为全生命周期、可视生命周期和活动生命周期。
每种生命周期中包含不同的事件回调函数。
全生命周期
全生命周期是从Activity建立到销毁的全部过程,始于onCreate(),结束于onDestroy()。
使用者通常在onCreate()中初始化Activity所能使用的全局资源和状态,并在onDestroy()中释放这些资源。
在一些极端的情况下,Android系统会不调用onDestroy()函数,而直接终止进程。
可视生命周期
可视生命周期是Activity在界面上从可见到不可见的过程,开始于onStart(),结束于onStop()。
onStart():一般用来初始化或启动与更新界面相关的资源。
onStop():一般用来暂停或停止一切与更新用户界面相关的线程、计时器和服务。
onRestart():函数在onSart()前被调用,用来在Activity从不可见变为可见的过程中,进行一些特定的处理过程。
onStart()和onStop()会被多次调用。
活动生命周期
活动生命周期是Activity在屏幕的最上层,并能够与用户交互的阶段,开始于onResume(),结束于onPause()。
在Activity的状态变换过程中onResume()和onPause()经常被调用,因此这两个函数中应使用更为简单、高效的代码。
public class MainActivity extends AppCompatActivity {
private static String TAG="LIFECYCLE";
//完全生命周期开始时被调用,初始化Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG,"(1)onCreate()");
}
//可视生命周期开始时被调用,对用户界面进行必要的更改
@Override
public void onStart(){
super.onStart();
Log.i(TAG, "(2) onStart()");
}
//在onStart()后被调用,用于恢复onSaveInstanceState()保存的用户界面信息
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "(3) onRestoreInstanceState()");
}
//在活动生命周期开始时被调用,恢复被onPause()停止的用于界面更新的资源
@Override
public void onResume() {
super.onResume();
Log.i(TAG, "(4) onResume()");
}
// 在onResume()后被调用,保存界面信息
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i(TAG, "(5) onSaveInstanceState()");
}
//在重新进入可视生命周期前被调用,载入界面所需要的更改信息
@Override
public void onRestart() {
super.onRestart();
Log.i(TAG, "(6) onRestart()");
}
//在活动生命周期结束时被调用,用来保存持久的数据或释放占用的资源
@Override
public void onPause() {
super.onPause();
Log.i(TAG, "(7) onPause()");
}
//在可视生命周期结束时被调用,一般用来保存持久的数据或释放占用的资源
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "(8) onStop()");
}
//在完全生命周期结束时被调用,释放资源,包括线程、数据连接等
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "(9) onDestroy()");
}
}
上面的程序主要通过在生命周期函数中添加“日志点”的方法进行调试,程序的运行结果将会显示在LogCat中
为了显示结果易于观察和分析,在LogCat设置过滤器LifeCycleFilter,过滤方法选择by Log Tag,过滤关键字为LIFTCYCLE
全生命周期:
(1)onCreate → (2)onStart → (4)onResume →(7)onPause → (8)onStop → (9)onDestroy
可视生命周期:
(1)onCreate → (2)onStart → (4)onResume → (7)onPause → (5)onSaveInstanceState → (8)onStop → (6)onRestart → (2)onStart → (4)onResume
Android用户界面
Android用户界面框架
MVC模型:控制器(处理用户输入),视图(显示用户界面和图像),模型(保存数据和代码)
Android用户界面框架采用视图树(View Tree)模型
View是最基本的可视单元存储了屏幕上特定矩形区域内所显示内容的数据结构,实现所占据区域的界面绘制、焦点变化、用户输入和界面事件处理等。一个重要的基类,所有在界面上的可见元素都是View的子类。ViewGroup是一种能够承载含多个View的显示单元。
常见的系统控件
TextView和EditText
首先是在xml中配置控件,大佬一般是手写xml,但是对于我这种小白还是喜欢用design模式,然后再对xml代码做适当的修改。
TextView是一种用于显示字符串的控件。
EditText则是用来输入和编辑字符串的控件。
<TextView
android:id="@+id/textView"
android:layout_width="108dp"
android:layout_height="22dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/editTextTextPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.052"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.848"
tools:ignore="MissingConstraints" />
<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Name"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.079"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.223"
tools:ignore="MissingConstraints" />
效果:
Button和ImageButton
(1)Button是一种按钮控件,用户能够在该控件上点击,并后引发相应的事件处理函数.
(2)ImageButton用以实现能够显示图像功能的控件按钮.
xml文件
mainactivity文件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建一个Button类按钮
Button button=(Button)findViewById(R.id.button);
//创建一个ImageButton类的按钮
ImageButton imageButton=(ImageButton)findViewById(R.id.imageButton);
//创建一个edittext变量通过id关联到EditText控件
EditText editText=(EditText) findViewById(R.id.editTextTextPersonName);
//点击确认按钮输出值
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String string=editText.getText().toString();
Toast.makeText(MainActivity.this, "你的名字是"+string, Toast.LENGTH_SHORT).show();
}
});
//设置监听点击按钮以后更换按钮图片
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageButton.setImageResource(R.drawable.download);
}
});
效果
点击前:
点击后:
Checkbox和RadioButton
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"
app:layout_constraintBottom_toTopOf="@+id/checkBox2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.078"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.917" />
<CheckBox
android:id="@+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.078"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.247" />
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="106dp"
android:layout_height="wrap_content"
android:text="不喜欢" />
<RadioButton
android:id="@+id/radioButton"
android:layout_width="106dp"
android:layout_height="wrap_content"
android:text="喜欢" />
</LinearLayout>
mainactivity文件
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private CheckBox checkBox,checkBox2;
private RadioButton radioButton,radioButton2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkBox=(CheckBox) findViewById(R.id.checkBox);
checkBox2=(CheckBox) findViewById(R.id.checkBox2);
radioButton=(RadioButton)findViewById(R.id.radioButton);
radioButton2=(RadioButton)findViewById(R.id.radioButton2);
checkBox.setOnClickListener(this);
checkBox.setTag(1);
checkBox2.setOnClickListener(this);
checkBox2.setTag(2);
radioButton.setOnClickListener(this);
radioButton.setTag(3);
radioButton2.setOnClickListener(this);
radioButton2.setTag(4);
}
@Override
public void onClick(View v) {
int m=(Integer) v.getTag();
switch (m){
case 1:
Toast.makeText(MainActivity.this, "你是男生", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this, "你是女生", Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(MainActivity.this, "你喜欢这个布局", Toast.LENGTH_SHORT).show();
break;
case 4:
Toast.makeText(MainActivity.this, "你不喜欢这个布局", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
效果
Spinner
一种能够从多个选项中选一选项的控件,使用浮动菜单为用户提供选择。
xml文件
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="109dp"
android:layout_weight="1" />
mainactivity文件
Spinner spinner=(Spinner)findViewById(R.id.spinner);
List<String> list=new ArrayList<String>();
list.add("添加");
list.add("删除");
list.add("修改");
ArrayAdapter<String>adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
效果
ListView
ListView是一种用于垂直显示的列表控件,如果显示内容过多,则会出现垂直滚动条。
xml文件
<ListView
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
mainactivity文件
ListView listView=(ListView) findViewById(R.id.listview);
List<String>list1=new ArrayList<String>();
list1.add("第一项");
list1.add("第二项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
list1.add("第三项");
ArrayAdapter<String>adapter1=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,list1);
listView.setAdapter(adapter1);