一、题型
1、选择题(10小题×2分,共20分,不写多选为单选)
2、判断题(10小题×1分,共10分)
3、简答题(5小题×6分,共30分)
4、程序代码填空题(14空×2分,共28分)
5、论述题(12分)
二、考点
1、Android的概念、特点和体系结构;
2、常见布局、属性设置;
3、常用控件、常用属性;
4、清单文件的配置、布局文件的控件及属性设置;
5、Activity的特点、生命周期、涉及的方法;
6、Intent
两种意图的实现;
Activity跳转的程序;
Activity跳转时传递参数的程序(startActivity和startActivityForResult)
7、IntentFilter
8、数据存储方式
文件存储
SharedPreferences存储
SQLite数据库简介
SQLite数据库的操作实现
数据适配器
9、内容提供者和内容观察者
ContentProvider作用
ContentResolver获取共享数据
ContentObserver作用
10、广播机制
有序广播、无序广播概念及区别、注册
有序广播拦截实现
11、服务
服务的概念,其与Activity的区别
服务的启动方式实现、生命周期
媒体播放(SurfaceView)
12、网络编程(使用HttpURLConnection访问网络)
第一章 Android基础入门
一、Android简介
安卓(Android)是一种基于Linux内核(不包含GNU组件)的自由及开源的操作系统。
二、Android体系结构
Android系统架构从高到低分为四层,分别为依次是应用程序层(Applications)、应用程序框架层(Application Framework)、核心类库(Libraries)和Linux内核(Linux Kernel),各层的特点具体如下:
1、应用程序层
一个核心应用程序的集合,安装在手机中的应用程序都属于这一层。
2、应用程序架构层
主要提供了构建应用程序时用到的各种API。例如活动管理器、通知管理器、内容提供者等。
3、核心类库
主要包含系统库和Android运行环境。
4、Linux内核层
为Android设备的各种硬件提供了底层的驱动,如:显示驱动、音频驱动、照相机驱动、蓝牙驱动等。
三、资源的管理与使用(了解即可)
1、图片资源
应用图标资源位置:mipmap文件夹中
界面中使用的图片资源位置:drawable文件夹中
(1)通过Java代码调用图片资源
//调用mipmap文件夹中资源文件
getResources().getDrawable(R.mipmap.ic_launcher);
//调用以drawable开头的文件夹中的资源文件
getResources().getDrawable(R.drawable.icon);
(2)在XML布局文件中调用图片资源
//调用mipmap文件夹中的资源文件
@mipmap/ic_launcher
//调用以drawable开头的文件夹中的资源文件
@drawable/icon
2、主题和样式资源
主题资源定义位置:res/values目录下的styles.xml文件中
样式资源定义位置:res/values目录下的styles.xml文件中
(1)在AndroidManifest.xml文件中设置主题
android:theme ="@style/AppTheme"
(2)在Java代码中设置主题
setTheme(R.style.AppTheme);
(3)在XML布局文件中引用样式
style="@style/textViewSytle"
3、布局资源
布局资源存放位置:res/layout文件夹中
(1)通过Java代码调用布局资源文件
//在Activity的onCreate()方法中调用activity_main.xml布局文件
setContentView(R.layout.activity_main);
(2)在XML布局文件中调用布局资源文件
//在XML布局文件中调用activity_main.xml布局文件
<include layout="@layout/activity_main"/>
4、字符串资源
字符串资源定义位置:res/values目录下的strings.xml文件中
(1)通过Java代码调用字符串资源
getResources().getString(R.string.app_name);
(2)在XML布局文件中调用字符串资源
@string/app_name
5、颜色资源
颜色资源定义位置:res/values/colors.xml文件中
(1)通过Java代码调用颜色资源
getResources().getColor(R.color.colorPrimary);
(2)在XML布局文件中调用颜色资源
@color/colorPrimary
6、尺寸资源
尺寸资源定义位置:res/values/dimens.xml文件中,如果程序中没有dimens.xml文件,可自行创建。
(1)通过Java代码调用尺寸资源
getResources().getDimension(R.dimen.activity_horizontal_margin);
(2)在XML布局文件中调用尺寸资源
@dimen/activity_horizontal_margin
第二章 Android常见页面布局
一、View视图
所有的UI元素都是通过View与ViewGroup构建的,对于一个Android应用的用户界面来说,ViewGroup作为容器盛装界面中的控件,它可以包含普通的View控件,也可以包含ViewGroup。
二、界面布局编写方式
1、在XML文件中编写布局
有效的将界面中的布局代码与Java代码隔离,使程序的结构更加清晰(推荐此种方式编写布局)。
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="使用XML布局文件控制UI界面"
android:textColor="#ff0000"
android:textSize="18sp"
android:layout_centerInParent="true"/>
</RelativeLayout>
2、在Java代码中编写布局
在Android中所有布局和控件的对象都可以通过new关键字创建出来,将创建的View控件添加到ViewGroup布局中,从而实现View控件在布局界面中显示。
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT); //设置布局中的控件居中显示
TextView textView = new TextView(this); //创建TextView控件
textView.setText("Java 代码实现界面布局"); //设置TextView的文字内容
textView.setTextColor(Color.RED); //设置TextView的文字颜色
textView.setTextSize(18); //设置TextView的文字大小
relativeLayout.addView(textView, params); //添加TextView对象和TextView的布局属性
setContentView(relativeLayout); //设置在Activity中显示RelativeLayout
三、界面布局的通用属性
属性名称 | 功能描述 |
---|---|
android:id | 设置布局的标识(在XML文件中它的属性值是通过“@+id/属性名称”定义) |
android:layout_width | 设置布局的宽度(系统定义的值有fill_parent、match_parent和wrap_content) |
android:layout_height | 设置布局的宽度(系统定义的值有fill_parent、match_parent和wrap_content) |
android:background | 设置布局的背景(其值可以引用图片资源,也可以是颜色资源) |
android:layout_margin | 设置当前布局与屏幕边界或与周围控件的距离 |
android:padding | 设置当前布局与该布局中控件的距离 |
四、线性布局
LinearLayout(线性布局)通常指定布局内的子控件水平或者竖直排列。
在XML布局文件中定义线性布局的基本语法格式如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
属性 = "属性值"
......>
</LinearLayout>
除了布局的通用属性外,LinearLayout布局还有两个比较常用的属性:
属性名称 | 功能描述 |
---|---|
android:orientation | 设置布局内控件的排列顺序(可选值为vertical[竖直排列]和horizontal[水平排列]) |
android:layout_weight | 在布局内设置控件权重(可使布局内的控件按照权重比显示大小),属性值可直接写int值 |
※ 注意:当控件使用权重属性时,布局宽度属性值通常设置为0dp。
五、相对布局
RelativeLayout(相对布局)通过相对定位的方式指定子控件的位置。
在XML布局文件中定义相对布局的基本语法格式如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
属性 = "属性值"
......>
</RelativeLayout>
在RelativeLayout中的子控件具备一些属性,用于指定子控件的位置,这些子控件的属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:layout_centerInParent | 设置当前控件位于父布局的中央位置 |
android:layout_centerVertical | 设置当前控件位于父布局的垂直居中位置 |
android:layout_centerHorizontal | 设置当前控件位于父控件的水平居中位置 |
android:layout_above | 设置当前控件位于某控件上方 |
android:layout_below | 设置当前控件位于某控件下方 |
android:layout_toLeftOf | 设置当前控件位于某控件左侧 |
android:layout_toRightOf | 设置当前控件位于某控件右侧 |
android:layout_alignParentTop | 设置当前控件是否与父控件顶端对齐 |
android:layout_alignParentLeft | 设置当前控件是否与父控件左对齐 |
android:layout_alignParentRight | 设置当前控件是否与父控件右对齐 |
android:layout_alignParentBottom | 设置当前控件是否与父控件底端对齐 |
android:layout_alignTop | 设置当前控件的上边界与某控件的上边界对齐 |
android:layout_alignBottom | 设置当前控件的下边界与某控件的下边界对齐 |
android:layout_alignLeft | 设置当前控件的左边界与某控件的左边界对齐 |
android:layout_alignRight | 设置当前控件的右边界与某控件的右边界对齐 |
※ 注意:在RelativeLayout布局中定义的控件默认与父布局左上角对齐。
六、表格布局
TableLayout(表格布局)采用行、列的形式来管理控件,通过在TableLayout布局中添加TableRow布局或控件来控制表格的行数,可以在TableRow布局中添加控件来控制表格的列数。
在XML布局文件中定义表格布局的基本语法格式如下:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
属性 = "属性值">
<TableRow>
UI控件
</TableRow>
UI控件
......
</TableLayout>
TableLayout继承自LinearLayout,因此它完全支持LinearLayout所支持的属性。
此外它还有其他的常用属性,TableLayout及其中常见控件的常用属性分别如下表所示:
属性名称 | 功能描述 |
---|---|
android:stretchColumns | 设置该列被拉伸 |
android:shrinkColumns | 设置该列被收缩 |
android:collapseColumns | 设置该列被隐藏 |
属性名称 | 功能描述 |
---|---|
android:layout_column | 设置该单元显示位置 |
android:layout_span | 设置该单元格占据几列,默认为1列 |
七、帧布局
FrameLayout(帧布局)用于在屏幕上创建一块空白区域,添加到该区域中的每个子控件占一帧,这些帧会一个一个叠加在一起,后加入的控件会叠加在上一个控件上层。默认情况下,帧布局中的所有控件会与左上角对齐。
在XML布局文件中定义帧布局的基本语法格式如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
属性 ="属性值">
</FrameLayout>
帧布局除了前面小节介绍的通用属性外,还有两个特殊属性,FrameLayout的2个特殊属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:foreground | 设置帧布局容器的前景图像(始终在所有子控件之上) |
android:foregroundGravity | 设置前景图像显示的位置 |
第三章 Android常见界面控件
一、TextView控件
TextView控件用于显示文本信息,可以在XML布局文件中以添加属性的方式来控制TextView控件的样式。
TextView控件的属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:layout_width | 设置TextView控件的宽度 |
android:layout_height | 设置TextView控件的高度 |
android:id | 设置TextView控件的唯一标识 |
android:background | 设置TextView控件的背景 |
android:layout_margin | 设置当前控件与屏幕边界或周围控件、布局的距离 |
android:padding | 设置TextView控件与该控件中内容的距离 |
android:text | 设置文本内容 |
android:textColor | 设置文字显示的颜色 |
android:textSize | 设置文字大小,推荐单位为sp |
android:gravity | 设置文本内容的位置 |
android:maxLength | 设置文本最大长度,超出此长度的文本不显示 |
android:lines | 设置文本的行数,超出此行数的文本不显示 |
android:maxLines | 设置文本的最大行数,超出此行数的文本不显示。 |
android:ellipsize | 设置当文本超出TextView规定的范围的显示方式。 |
android:drawableTop | 在文本的顶部显示图像 |
android:lineSpacingExtra | 设置文本的行间距 |
android:textStyle | 设置文本样式,如bold(粗体),italic(斜体),normal(正常) |
二、EditText控件
EditText表示编辑框,它是TextView的子类,用户可在此控件中输入信息。
除了支持TextView控件的属性外,EditText还支持一些其它的常用属性,这些常用属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:hint | 控件中内容为空时显示的提示文本信息 |
android:textColorHint | 控件中内容为空时显示的提示文本信息的颜色 |
android:password | 输入文本框中的内容显示为“.” |
android:phoneNumber | 设置输入文本框中的内容只能是数字 |
android:maxLines | 设置文本的最大行数 |
android:scrollHorizontally | 设置文本信息超出EditText的宽度情况下,是否出现横拉条 |
android:editable | 设置是否可编辑 |
三、Button控件
Button控件表示按钮,它继承TextView控件,既可以显示文本,又可以显示图片,同时也允许用户通过点击来执行操作,当Button控件被点击时,被按下与弹起的背景会有一个动态的切换效果,这个效果就是点击效果 。
(1)在布局文件中指定onClick属性的方式设置点击事件
<Button
......
android:onClick="click" />
(2)使用匿名内部类的方式设置点击事件
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//实现点击事件的代码
}
});
(3)Activity实现OnClickListener接口的方式设置点击事件
public class Activity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
......
btn.setOnClickListener(this); //设置Button控件的点击监听事件
}
@Override
public void onClick(View view) {
//实现点击事件的代码
}
}
※ 注意:实现Button控件的点击事件的三种方式中,前两种方式适合界面上Button控件较少的情况,如果界面上Button控件较多时,建议使用第三种方式实现控件的点击事件。
四、ImageView控件
ImageView控件表示图片,它继承自View,可以加载各种图片资源。
ImageView控件的常用属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:layout_width | 设置ImageView控件的宽度 |
android:layout_height | 设置ImageView控件的高度 |
android:id | 设置ImageView控件的唯一标识 |
android:background | 设置ImageView控件的背景 |
android:layout_margin | 设置当前控件与屏幕边界或周围控件的距离 |
android:src | 设置ImageView控件需要显示的图片资源 |
android:scaleType | 将图片资源缩放或移动,以适应ImageView控件的宽高 |
android:tint | 将图片渲染成指定的颜色 |
五、RadioButton控件
RadioButton表示单选按钮,它是Button的子类。每一个单选按钮都有“选中”和“未选中”两种状态,这两种状态是通过android:checked属性指定的。当可选值为true时,表示选中状态,否则,表示未选中状态。
在XML布局文件中,RadioGroup和RadioButton配合使用的语法格式如下:
<RadioGroup
android:属性名称 ="属性值"
......>
<RadioButton
android:属性名称 ="属性值"
...... />
......
<RadioGroup/>
六、CheckBox控件
CheckBox表示复选框,它是Button的子类,用于实现多选功能。每一个复选框都有“选中”和“未选中”两种状态,这两种状态是通过android:checked属性指定的,当该属性的值为true时,表示选中状态,否则,表示未选中状态。
activity_main.xml
......
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="...sp"
android:text="textname"
android:id="@+id/x"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="...sp"
android:text="textname"
android:id="@+id/y"/>
......
<TextView
android:id="@+id/xy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="...sp"
android:textColor="#FF8000"/>
Mainactivity.java
public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener{
private TextView xy;
private String xys;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化CheckBox控件
CheckBox x = (CheckBox)findViewById(R.id.x);
CheckBox y = (CheckBox)findViewById(R.id.y);
x.setOnCheckedChangeListener(this);
y.setOnCheckedChangeListener(this);
xy = (TextView)findViewById(xy);
//用来存放选中的CheckBox信息
xys = new String();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// buttonView 表示被点击的控件, isChecked 表示控件状态
String motion = buttonView.getText().toString();
// 通过 isChecked 判断当前被点击的 CheckBox 是否为选中状态
if(isChecked){ // 选中状态
if(!xys.contains(motion)){ // xys 字符串中不包含 CheckBox 的文本信息
xys = xys + motion; // 将文本信息添加到 xys 字符串中
xy.setText(xys); // 显示在 TextView 上
}else { // 未选中状态
if (xys.contains(motion)){ // xys 字符串中包含 CheckBox 的文本信息
xys = xys.replace(motion,""); // 使用空字符串替换 CheckBox 的文本信息
xy.setText(xys); // 将返回的 xys 字符串显示在 TextView 上
}
}
}
}
}
七、Toast类
Toast是Android系统提供的轻量级信息提醒机制,用于向用户提示即时消息,它显示在应用程序界面的最上层,显示一段时间后自动消失不会打断当前操作,也不获得焦点。
使用Toast显示提示信息的示例代码如下:
Toast.makeText(Context,Text,Time).show();
关于makeText()方法中参数的相关介绍具体如下:
- Context:表示应用程序环境的信息,即当前组件的上下文环境。
- Text:表示提示的字符串信息。
- Time:表示显示信息的时长,其属性值包括Toast.LENGTH_SHORT和Toast.LENGTH_LONG,分别表示显示较短时间和较长时间。
使用Toast提示用户“WIFI已断开”的信息,示例代码如下:
Toast.makeText(MainActivity.this, "WIFI已断开", Toast.LENGTH_SHORT).show();
八、ListView控件
ListView以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示。
ListView的样式是由属性决定的,它的常用属性如下表所示:
属性名称 | 功能描述 |
---|---|
android:listSelector | 当条目被点击后,改变条目的背景颜色 |
android:divider | 设置分割线的颜色 |
android:dividerHeight | 设置分割线的高度 |
android:scrollbars | 是否显示滚动条 |
android:fadingEdge | 去掉上边和下边的黑色阴影 |
在XML文件的RelativeLayout布局中添加ListView控件的示例代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
......>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="#fefefefe"
android:scrollbars="none">
</ListView>
</RelativeLayout>
九、ListView与RecyclerView的区别
- 展示效果:RecyclerView控件可以通过LayoutManager类实现横向或竖向的列表效果、瀑布流效果和GridView效果,而ListView控件只能实现竖直的列表效果。
- 适配器:RecyclerView控件使用的是RecyclerView.Adapter适配器,该适配器将BaseAdapter中的getView()方法拆分为onCreateViewHolder()方法和onBindViewHolder()方法,强制使用ViewHolder类,使代码编写规范化,避免了初学者写的代码性能不佳。
- 复用效果:RecyclerView控件复用Item对象的工作由该控件自己实现,而ListView控件复用Item对象的工作需要开发者通过convertView的setTag()方法和getTag()方法进行操作。
- 动画效果:RecyclerView控件可以通过setItemAnimator()方法为Item添加动画效果,而ListView控件不可以通过该方法为Item添加动画效果。
※ 实战演练——实现注册界面效果
十、数据适配器
数据适配器是数据与视图之间的桥梁,它类似于一个转换器,将复杂的数据转换成用户可以接受的方式进行呈现。
1、BaseAdapter
基本的适配器,实际上是一个抽象类,通常在自定义适配器时会继承BaseAdapter,该类拥有四个抽象方法,根据这几个抽象方法对ListView控件进行数据适配。BaseAdapter中的4个抽象方法如下表所示:
方法名称 | 功能描述 |
---|---|
public int getCount() | 获取列表条目的总数 |
public Object getItem(int position) | 根据position(位置)获取某个条目的对象 |
public long getItemId(int position) | 根据position(位置)获取某个条目的id |
public View getView(int position, View convertView, ViewGroup parent) | 获取相应position对应的条目视图,position是当前条目的位置,convertView用于复用旧视图,parent用于加载XML布局。 |
2、SimpleAdapter
BaseAdapter的子类,实现了BaseAdapter的四个抽象方法并进行封装。SimpleAdapter的构造方法的具体信息如下:
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to)
// context:表示上下文对象。
// data:数据集合, data中的每一项对应ListView控件中的条目的数据。
// resource:条目布局的资源id。
// from:Map集合中的key值。
// to:条目布局中对应的控件。
3、ArrayAdapter
BaseAdapter的子类,用法与SimpleAdapter类似,只需要在构造方法里面传入相应参数即可。ArrayAdapter通常用于适配TextView控件,ArrayAdapter有多个构造方法,构造方法的具体信息如下所示:
public ArrayAdapter(Context context,int resource);
public ArrayAdapter(Context context,int resource, int textViewResourceId);
public ArrayAdapter(Context context,int resource,T[] objects);
public ArrayAdapter(Context context,int resource,int textViewResourceId,T[] objects);
public ArrayAdapter(Context context,int resource,List<T> objects);
public ArrayAdapter(Context context,int resource,int textViewResourceId, List<T> objects)
// context:上下文对象
// resource:条目布局的资源id
// textViewResourceId:条目布局中对应的TextView控件的id
// objects:需要适配的List类型的数
第四章 程序活动单元Activity
一、Activity的生命周期
Activity的生命周期包括创建、可见、获取焦点、失去焦点、不可见、重新可见、销毁等环节,针对每个环节Activity都定义了相关的回调方法,Activity中的回调方法具体如下。
- onCreate():Activity创建时调用,通常做一些初始化设置。
- onStart():Activity即将可见时调用。
- onResume():Activity获取焦点时调用。
- onPause():当前Activity被其他Activity覆盖或屏幕锁屏时调用。
- onStop():Activity对用户不可见时调用。
- onRestart():Activity从停止状态到再次启动时调用。
- onDestroy():Activity销毁时调用。
※ 启动和关闭Activity
-
启动Activity
-
startActivity()方法
-
public void startActivity(Intent intent)
以启动SecondActivity为例,示例代码如下:
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
-
关闭Activity
-
finish()方法
-
public void finish()
以MainActivity中按钮的点击事件中关闭Activity为例,示例代码如下:
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
@Override
Public void onClick(View v){
finish();
}
});
二、Intent
Intent被称为意图,它不仅可以指定当前组件要执行的动作,还可以在不同组件之间进行数据传递。根据开启目标组件的方式不同,Intent被分为两种类型,分别为显式Intent和隐式Intent。
1、显式意图
显式Intent指的是直接指定目标组件,例如,使用Intent显式指定要跳转的目标Activity,示例代码如下:
Intent intent = new Intent(this, SecondActivity.class); // (当前Activity, 要启动的Activity)
startActivity(intent); // 启动Activity
2、隐式意图
隐式Intent不会明确指出需要激活的目标组件,它被广泛地应用在不同应用程序之间传递消息。
Android系统会使用IntentFilter匹配属性action、data、category,这3个属性的具体介绍如下:
- action:表示Intent对象要完成的动作。
- data:表示Intent对象中传递的数据。
- category:表示为action添加的额外信息。
在清单文件中,配置SecondActivity的action为“cn.itcast.START_ACTIVITY”的代码如下所示:
<activity android:name=".SecondActivity">
<intent-filter>
// 设置action动作,当代码中的action与该action相匹配时启动该组件
<action android:name="cn.itcast.START_ACTIVITY"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
在程序的MainActivity中开启SecondActivity的示例代码如下:
Intent intent = new Intent();
intent.setAction("cn.itcast.START_ACTIVITY"); //设置action动作,当与清单文件中的action相匹配时启动目标组件
startActivity(intent);
※ 使用隐式Intent开启Activity时,系统会默认为该Intent添加category的属性name的值为“android.intent.category.DEFAULT ”,所以将SecondActivity对应的<category/>标签中,属性android:name的值设置为“android.intent.category.DEFAULT”。
三、IntentFilter
当发送一个隐式Intent后,Android系统会将它与程序中的每一个组件的过滤器进行匹配,匹配属性有action、data和category,需要这3个属性都匹配成功才能唤起相应的组件。
1、action属性匹配规则
action属性用来指定Intent对象的动作,具体示例代码如下:
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
......
</intent-filter>
只要Intent携带的action与其中一个<intent-filter>标签中action的声明相同,action属性就匹配成功。在清单文件中为Activity添加<intent-filter>标签时,必须添加action属性,否则隐式Intent无法开启该Activity。
2、data属性匹配规则
data属性用来指定数据的URI或者数据MIME类型,它的值通常与Intent的action属性有关联,具体示例代码如下:
<intent-filter>
<data android:mimeType="video/mpeg" android:scheme="http......" />
<data android:mimeType="audio/mpeg" android:scheme="http......" />
......
</intent-filter>
隐式Intent携带的data数据只要与IntentFilter中的任意一个data声明相同,data属性就匹配成功。
3、category属性匹配规则
category属性用于为action添加额外信息,一个IntentFilter可以不声明category属性,也可以声明多个category属性,具体示例代码如下:
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
......
</intent-filter>
一个IntentFilter可以不声明category属性,也可以声明多个category属性。隐式Intent中声明的category必须全部能够与某一个IntentFilter中的category匹配才算匹配成功。IntentFilter中罗列的category属性数量必须大于或者等于隐式Intent携带的category属性数量时,category属性才能匹配成功。如果一个隐式Intent没有设置category属性,那么他可以通过任何一个IntentFilter(过滤器)的category匹配。
四、Activity之间的跳转
1、Activity之间的数据传递
Android提供的Intent可以在界面跳转时传递数据。使用Intent传递数据有两种方式:
(1)使用Intent的putExtra()方法传递数据
Activity之间需要传递不同类型的数据,所以Android系统提供了多个重载的putExtra()方法。
在MainActivity中将数据传递给SecondActivity:
Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
intent.putExtra("studentName","王晓明");
intent.putExtra("englishScore",98);
intent.putExtra("isPassed",true);
startActivity(intent);
在SecondActivity 中获取MainActivity传递来的数据:
Intent intent = getIntent();
String name = intent.getStringExtra("studentName");
int englishScore = intent.getIntExtra("englishScore",0);
boolean isPassed = intent.getBooleanExtra("isPassed",true);
(2)使用Bundle类传递数据
将用户名数据封装到Bundle对象中:
Intent intent = new Intent();
intent.setClass(this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("account", "王小明");
bundle.putString("password", "123456");
intent.putExtras(bundle);
startActivity(intent);
通过Bundle对象获取用户名信息:
Bundle bundle = getIntent().getExtras();
String account = bundle.getString("account");
String password = bundle.getString("password");
2、Activity之间的数据回传
Activity之间进行数据回传时包含3个方法,分别是startActivityForResult()方法、setResult()方法和onActivityResult()方法。
(1)startActivityForResult()方法
用于开启一个Activity,当开启的Activity销毁时,会从销毁的Activity中返回数据:
startActivityForResult(Intent intent, int requestCode) //(意图对象, 用于标识请求来源的请求码)
(2)setResult() 方法
用于携带数据进行回传,该方法的语法格式如下:
setResult(int resultCode, Intent intent) // 用于标识返回数据来自哪一个 Activity 的返回码
(3)onActivityResult()方法
用于接收回传的数据,该方法的语法格式如下:
onActivityResult(int requestCode, int resultCode, Intent data) // (请求码, 回传码, 回传数据)
程序会根据传递的参数requestCode与resultCode来识别数据的来源。
※ 示例:
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent,1); // 开启 SecondActivity
Intent intent = new Intent();
intent.putExtra("data","Hello MainActivity");
setResult(2,intent); // 在 SecondActivity 中添加返回数据
finish();
@Override
// SecondActivity 被销毁之后在 MainActivity 中回调 onActivityResult() 方法,接收回传的数据
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1&&resultCode == 2){
String acquiredData= data.getStringExtra("data");
Toast.makeText(MainActivity.this,acquiredData,Toast.LENGTH_SHORT).show();
}
}
※ 实战演练——小猴子摘桃
五、Fragment
Fragment不能独立存在,必须嵌入到Activity中使用,所以Fragment生命周期直接受所在的Activity影响:
-
当在Activity中创建Fragment时,Fragment处于启动状态;
-
当Activity被暂停时,其中的所有Fragment也被暂停;
-
当Activity被销毁时,所有在该Activity中的Fragment也被销毁。
-
当一个Activity处于运行状态时,可以单独地对每一个Fragment进行操作,如添加或删除:
-
当添加时,Fragment处于启动状态。
-
当删除时,Fragment处于销毁状态。
-
-
onAttach():当fragment和activity建立关联的时候调用
-
onCreateView():为fragment创建视图调用,在onCreate之后
-
onActivityCreated():确保与fragment相关联的activity一定已经创建完毕的时候调用
-
onDestroyView():当与fragment关联的视图被移除的时候调用
-
onDetach():当fragment与activity解除关联时调用
第五章 数据存储
一、文件存储
※ 实战演练——保存QQ账号与密码
二、SharedPreferences存储
SharedPreferences是Android平台上一个轻量级的存储类,用于持久化存储程序中一些少量数据。
1、将数据存入SharedPreferences中
SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit(); // 获取编辑器
editor.putString("name", "张三"); // 以 key/value 的形式保存数据
editor.putInt("age", 8); // value值只能是float、int、long、boolean、String、Set<String>类型数据
editor.commit(); // 提交数据
2、读取与删除SharedPreferences中的数据
(1)读取
SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE);
String data = sp.getString("name",""); // 获取用户名信息,第1个参数表示用户名数据的key值,第2个参数表示缺省值
(2)删除
editor.remove("name"); // 删除key值为name的数据
editor.clear(); // 删除所有数据
※ 注意:
-
获取数据的key值与存入数据的key值的数据类型要一致,否则查找不到指定数据
-
保存SharedPreferences的key值时,使用静态变量保存,以免操作时写错,如private final String key = “itcast”
※ 实战演练——保存QQ账号与密码
三、SQLite数据库存储
1、SQLite简介
- SQLite是Android自带的一个轻量级的数据库,它运算速度快,占用资源少,支持基本SQL语法。
- SQLite数据库可以存储应用程序中的大量数据,并对数据进行管理和维护。
- SQLite保存数据时,支持NULL(零)、INTEGER(整数)、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)五种数据类型。实际还接收varchar(n),char(n),decimal(p,s)。
- SQLite没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使用。
2、SQLite的创建与使用
public class MyHelper extends SQLiteOpenHelper {
public MyHelper(Context context) {
// context:表示上下文
// itcast.db:数据库名称
// null:游标工厂,此处设为null
// 2:数据库版本号
super(context, "itcast.db", null, 2);
}
public void onCreate(SQLiteDatabase db) { // 数据库第一次被创建时调用,用于初始化表结构
db.execSQL("CREATE TABLE information(_id INTEGER PRIMARY
KEY AUTOINCREMENT, name VARCHAR(20), price INTEGER)");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} // 数据库的版本号增加时调用
}
3、SQLite数据库的基本操作
(1)添加数据
public void insert(String name,String price) {
MyHelper helper = new MyHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase(); // 获取可读写SQLiteDatabse对象
ContentValues values = new ContentValues();
// 将数据添加到ContentValues对象中
values.put("name", name);
values.put("price", price);
ong id = db.insert("information",null,values); // 调用insert()方法将数据添加到数据库中
db.close(); // 关闭数据库
}
(2)删除数据
public int delete(long id){
SQLiteDatabase db = helper.getWritableDatabase();
// 调用delete()方法删除数据库中的数据
int number = db.delete("information", "_id=?", new String[]{id+""});
db.close();
return number;
}
(3)修改数据
public int update(String name, String price) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", price); // 将修改的数据添加到values对象中
// 调用update()方法修改数据
int number = db.update("information", values, "name =?", new String[]{name});
db.close();
return number;
}
(4)查询数据
public void find(int id){
MyHelper helper = new MyHelper(MainActivity.this);
SQLiteDatabase db = helper.getReadableDatabase();
// 调用query()方法查询数据库中的数据,返回一个行数集合Cursor
Cursor cursor = db.query("information", null, "_id=?", new String[]{id+""},null, null, null);
if (cursor.getCount() != 0){ // 判断查询到的数据总条数不是0时
while (cursor.moveToNext()){ // 移动游标指向下一行数据
// 获取数据
String _id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String price = cursor.getString(cursor.getColumnIndex("price"));
}
......
}
4、SQLite数据库中的事务特征
- 原子性:表示事务是一个不可再分割的工作单位,事务中的操作要么全部成功,要么全部失败回滚。
- 一致性:表示事务开始之前和结束之后,数据库的完整性没有被破坏。也就是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
- 隔离性:表示并发的事务是相互隔离的,也就是一个事务内部的操作都必须封锁起来,不会被其他事务影响到。
- 持久性:表示事务一旦提交后,该事务对数据做的更改便持久保存在数据库中,并不会被回滚,即使出现了断电等事故,也不会影响数据库中的数据。
第六章 数据共享
一、ContentProvider
假设B程序需要操作A程序数据库中的数据,一般需要A程序使用ContentProvider暴露数据,才能被其他程序操作。B程序通过ContentResolver操作A程序暴露出来的数据,而A程序会将操作结果返回给ContentResolver,然后ContentResolver再将操作结果返回给B程序。
二、ContentObserver
使用ContentObserver观察A程序的数据时,首先要在A程序的ContentProvider中调用ContentResolver的notifyChange()方法。调用此方法后,当B程序操作A程序中的数据时,A程序会向“消息中心”发送数据变化的消息,此时C程序会观察到“消息中心”的数据有变化,会触发ContentObserver的onChange()方法。
第七章 广播机制
一、无序广播
无序广播是完全异步执行,发送广播时所有监听这个广播的广播接收者都会接收到此消息,但接收的顺序不确定。
二、有序广播
按照接收者的优先级接收,只有一个广播接收者能接收消息,在此广播接收者中逻辑执行完毕后,才会继续传递。
※ 注册
IntentFilter filter2 = new IntentFilter();
filter2.addAction("x.xx.xxx.有序");
filter2.setPriority(999);
this.registerReceiver(new Test2Receiver(), filter2);
IntentFilter filter1 = new IntentFilter();
filter1.addAction("x.xx.xxx.有序");
filter1.setPriority(1000);
this.registerReceiver(new Test1Receiver(), filter1);
IntentFilter filter3 = new IntentFilter();
filter3.addAction("x.xx.xxx.有序");
filter3.setPriority(998);
this.registerReceiver(new Test3Receiver(), filter3);
※ 拦截实现
若将广播接收者MyBroadcastReceiverTwo的优先级设置为1000,并将注册MyBroadcastReceiverTwo的语句放在注册MyBroadcastReceiverOne的语句前面,此时如果想要拦截一个有序广播,则必须在优先级较高的广播接收者中拦截接收到的广播,可以通过在优先级较高的MyBroadcastReceiverTwo中添加一个abortBroadcast()方法拦截广播(参考实战演练——数鸭子)。
※ 有序广播和无序广播的区别
-
发送广播时,使用的方法不同。有序广播使用sendOrderedBroadcast()发送广播,而无序广播使用sendBroadcast()方法发送广播。
-
广播接收者执行的顺序
-
有序广播的接收者是顺序执行的 有序广播按照广播接收者声明的优先级别被依次接收。当在高级别的广播接收者逻辑执行完毕之后,广播才会继续传递。当优先级相同时,先注册的广播接受者优先执行。
-
无序广播是完全异步执行的
当发送无序广播时,所有监听这个广播的广播接收者都会接收到此广播消息,但接收和执行的顺序不确定。
-
-
拦截广播
有序广播的接收者可拦截广播。若优先级较高的广播接收者将广播终止,那么广播将不再向后传递。而无序广播则不能被拦截。
-
效率
有序广播的效率比无序广播低。
第八章 服务
一、服务的概述
Service(服务)是Android四大组件之一,能够在后台长时间执行操作并且不提供用户界面的应用程序组件。Service可以与其他组件进行交互,一般是由Activity启动,但是并不依赖于Activity。当Activity的生命周期结束时,Service仍然会继续运行,直到自己的生命周期结束为止。Service还具有较长的时间运行特性,它的应用场景主要有两个,分别是后台运行和跨进程访问。
二、服务的启动方式
Service的启动方式分别可以调用startService()、bindService()方法,这两个启动方式的区别如下所示:
-
生命周期
-
startService()使用该方法开启Service时,执行的生命周期方法依次为onCreate()、onStartCommand()、onDestroy()
-
bindService()使用该方法开启Service时,执行的生命周期方法依次为onCreate()、onBind()、onUnbind()、onDestroy()
-
-
停止服务的方法
-
startService()调用stopSelf()、stopService()方法停止服务。
-
bindService()调用unbindService()方法停止服务。
-
-
组件的关联
-
startService()当一个组件通过此方法开启服务时,服务与开启该组件没有关联,即使开启服务的组件被销毁,服务依旧运行。
-
bindService()当一个组件通过此方法开启服务时,服务会与该组件绑定,组件一旦被销毁,该服务也会被销毁。
-
三、服务的生命周期
使用不同的方式启动服务,其生命周期会不同。开启服务的方法分别为startService()、bindService():
- 当通过startService()方法启动服务时,执行的生命周期方法依次为onCreate()、onStartCommand()、onDestroy()。
- 当通过bindService()方法启动服务时,执行的生命周期方法依次为onCreate()、onBind()、onUnbind()、onDestroy()。
其生命周期方法的具体含义如下:
- onCreate():第一次创建服务时执行的方法。
- onStartCommand():调用startService()方法启动服务时执行的方法。
- onBind():调用bindService()方法启动服务时执行的方法。
- onUnbind():调用unBindService()方法断开服务绑定时执行的方法。
- onDestory():服务被销毁时执行的方法。
※ Service和Activity的区别(个人总结)
- 进程启动了Service后,进程的优先级变高,一般情况系统不会kill该进程,而Activity不具备这样的特性
- Service和Activity的生命周期不一样,Service处在哪个生命周期是由程序控制的,而Activity处在哪个生命周期是由系统控制的,Service不能自己启动,而且不与用户交互
- Service是一种应用程序组件,可以在后台执行长时间运行的操作,并且不提供用户界面,而Activity不可以
- Service可以通过Binder实现跨进程调用,而Activity不处理跨进程调用的工作
- Service不仅可以给Activity建立双向连接,提供数据和功能支持,也可以单向接受Intent的请求,进行数据的分析处理和功能调度
※ 实战演练——仿网易音乐播放器
第九章 网络编程
使用HttpURLConnection访问网络
- 创建URL对象
- 调用URL对象的openConnection()方法获取HttpURLConnection对象
- 调用setRequestMethod()方法设置http请求的方式
- 通过setConnectTimeout()方法设置连接的超时时间
- 调用getInputStream()方法获取服务器返回的输入流
- 最后调用disconnect()方法关闭http连接