Android应用开发学习笔记

2.安卓UI开发

2.1 布局的创建

在Android中程序中的界面是通过布局文件设定的,在每个应用程序创建时会默认包含一个主界面布局,该布局位于res/layout目录中

实际开发中每个应用程序包含多个界面,而程序默认提供一个主界面布局无法满足需求,所以need添加布局

2.2 布局的类型

五大常见布局

1. 线性布局

以水平(默认)或者垂直方向排列

  • 当控件水平排列时,显示顺序依次为从左到右,当控件垂直排列时,显示顺序为从上到下。

    <LinearLayout xmlns:android="htt..."
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation='vertical'
    />
    <LinearLayout xmlns:android="htt..."
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation='horizontal'
    />
    
  • 当控件水平排列时,控件属性layout_width只能设置成wrap_content(包裹内容让当前控件根据控件内容大小自动伸缩)

  • 当控件水平排列时,如果控件未占满一行,会留白,此时可以利用layout_weight(权重),通过比例调节布局中所以控件的大小

    <Button
    android:layout_width='0dp'
    android:layout_height="wrap_content"
    android:layout_weight="2"
    />
    

2. 相对布局

通过相对定位排列,即以其他控件或者父容器作为参照物,拜访控件位置

  • 在设计相对布局时,要遵守控件之间的依赖关系,后放入的控件的位置依赖于先放入的控件。

    <RelativeLayout xmlns:android="..."
    android:layput_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="20dp"
    
    >
    </RelativeLayout>
    
  • 为了让程序适配:

    名称解释补充
    px像素在屏幕中可以显示的最小元素单位
    pt磅数一般作为字体的单位显示
    dp基于屏幕密度的抽象单位不同设备由不同的显示效果,根据设备的分辨率的不同来确定控件的尺寸
    sp可伸缩像素推荐设置文字大小时使用

3. 帧布局

开辟空白区域,帧里的控件(层)叠加

  • 为每个加入其中的控件创建一个空白区域(称为一帧,每个控件占据一帧)

  • 所以控件都默认显示在屏幕左上角,按照先后放入的顺序重叠摆放,帧布局的大小由内部最大控件决定

    <FrameLayout xmlns=""
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@mipmap/ic_launcher"
    android:foregroundGravity="left">
    </FrameLayout>
    

    eg:刮刮卡

4. 表格布局

表格形式排列,通过行和列将界面划分为多个单元格,每个单元格都可以添加控件

  • 表格布局需要配合TableRow使用,每一行都是由TableRow对象组成,所以TableRow的数量决定了表格的行数。表格的列数是由包含最多控件的TableRow决定

  • 表格布局属性

    布局属性功能描述
    android:stretchColumns该列被拉伸
    android:shrinkColumns该列被收缩
    android:collapseColumns该列被隐藏
  • 表格布局控件属性

    控件属性功能描述
    android:layout_column设置该单元显示位置
    android:layout_span设置该单元格占据几行,默认为1行
    <TableLayout xmlns:android=""
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:stetchColumns="2">
    	<TableRow>
    		<Button
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:layout_column="0"
    		android:text="按钮1"/>
    	</TableRow>
    </TableLayout>
    

5. 绝对布局

通过xy坐标排列

<AbsoluteLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent"
<Button
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_x="50dp"
	android:layout_y="50dp"
	android:text="按钮2"/>
</AbsoluteLayout>

2.3 常用控件

控件是界面组成的主要元素,是与用户进行直接交互的

常用控件

1. TextView

2. EditText

  • EditText继承自TextView,可以进行编辑操作,将用户信息传递给Android程序,还可以为EditText控件设置监听器,用来测试用户输入的内容是否合法。

    <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="请输入姓名"
    android:maxLines="2"
    android:textColor="#000000"
    android:textSize="20sp"
    android:textStyle="italic"/>
    

3. Button

用于响应用户的一系列点击事件,使得程序更加流畅完整

<Button
android:id="@+id/btn"
android:text="按钮"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="click"
/>
  • 指定Button的onClick属性方式

    • 首先在layout文件中指定onClick属性

      android:onClick="click"
      
    • 然后再Activity中实现这个click方法

      public void click(View v){
      	Log.i("指定onClick属性方式","button is clicked");
      }
      
  • 独立类方式

    • 首先为按钮设置监听器

      btn.setOnClickListener(myListener);
      
    • 在onCreate() 方法外实现接口

      onClickListener myListener=new OnClickListener(){
      public void onClick(View v){
      	Log.i("独立类方式","button is clicked")
      }
      }
      
  • 接口方式

    • 首先在当前Activity中实现OnClickListener接口
    • 然后实现接口方法
  • 匿名内部类方式

    在Activity中添加匿名内部类

    btn.seOnClickListener(new View.OnClickListener(){
    public void onClick(View v)
    	{Log.i("匿名内部类方式","button is clicked");}
    });
    

4. RadioButton

为单选按钮,它需要与RadioGroup配合使用,提供两个或多个互斥的选项集

RadioGroup是单选组合框,可容纳多个RadioButton,并把它们组合在一起,实现单选状态

<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientent="vertical">
<RadioButton
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="男"/>
<RadioButton
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="女"/>
</RadioGroup>
  • 利用setOnCheckedChangeListener()监听RadioGroup 状态,通过if语句判断被选中RadioButton的id
radioGroup.setOnClickedChangeListener(new RadioGroup.OnClickedChangeListener(){
public void onCheckedChange(RadioGroup group,int checkedId)
{
	if (checkedId==R.id.rbtn){
	textView.setText("您的性别是:男");
	}
	else
	{textView.setText("您的性别是:女");}
}
})

5. ImageView

是视图控件,继承自View,其功能是在屏幕中显示图像

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawble/bg"
/>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
amdroid:src=""/>

2.4 常见对话框

对话框是程序与用户交互的一种方式,通常用于显示当前程序提示信息以及相关说明

常见对话框:

1. 普通对话框

  • 一般只会显示提示信息,并具有确定和取消按钮

    方法名称功能描述
    setTitle()设置对话框标体
    setIcon()设置对话框图标
    setPositiveButton()给对话框添加确定按钮
    setNegativeButton()给对话框添加取消按钮
    setMessage()设置对话框提示信息
    AlertDialog dialog;
    dialog=new AlertDialog.Bulider(this)
    .setTitle("Dialog对话框")
    .setMessage("是否确定退出")
    .setIcon(R.mipmap.ic_launcher)
    .setPositiveButton("确定",null)
    .setNativeButton("取消",null)
    .create();
    dialog.show();
    

2. 单选对话框

单选对话框和RadioButton相似,只能选择一个选项,它是通过AlertDialog对象调用setSingleChoiceItems()方法创建

new AlertDialog.Bulider(this)
	.setTitle("请选择性别")
	.setIcon(R....)
	.setSingleChoiceItems(new String[]{"男""女"},0,new DialogInferface.OnClickListener(){
	public void onClick(DialogInferface dialog,int which){
	
	}
	})
	.setPositiveButton("确定",null)
	.show;

3. 多选对话框

多选对话框通常需要勾选多种选项时使用,创建多选对话框调用 setMultiChioseItems()

new AlterDialog.Bulder(this)
	.setTitle("请添加兴趣爱好")
	.setIcon(R....)
	.setMultiChoiceItems(new String[]{"A","B","C"},null,null)
	.setPositiveButton("确定",null)
	.show

4. 进度条对话框

进度条对话框一般在应用程序实现耗时操作时使用

ProgressDialog prodialog;
prodialog=new ProgressDialog(this);
prodialog.setTitle("进度条对话框");
prodialog.setIcon("....jpg");
prodialog.setMessage("正在下载请稍后。。。");
prodialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
prodialog.show;

5. 消息对话框

是轻量级消息提醒机制,显示在应用程序界面的最上层,一段时间后会自动消失不会打断当前操作,也不会获得焦点

Toast.makeTaxt(this,"Hello,Toast",Toast.LENGTH_SHORT).show();

6. 自定义对话框

创建自定义对话框的流程:

  • 创建布局:创建一个自定义对话框的布局文件(my_dialog.xml),布局中需要设定对话框的标题,对话框内容以及确定和取消按钮
  • 创建自定义对话框:创建一个类MyDialog继承自Dialog类,主要用于初始化自定义对话框中的控件以及响应按钮的点击事件
  • 使用自定义对话框:在MainActivity中,调用MyDialog的构造方法将自定义对话框显示出来

2.5 样式主题

1. 样式

style是一种包含一种或者多种控件的属性集合,可以指定控件高度,宽度,字体大小及颜色等

<resources>
    <style name="textStyle_one">
        <item name="android:layout_width">match_parent</item>
        <item name="andriod:layout_height">wrap_content</item>
        <item name="android:textColor">#000000</item>
        <item name="android:textSize">35dp</item>
    </style>
</resources>

采用自定义样式:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=....
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical">
	<TextView
		style="@style/textStyle_one"
		android:text="TextView样式1"
	/>
</LinearLayout>

2. 主题

theme是应用到整个Acitivity和Application的样式,当设置好主题后,Activity或整个程序中的视图都将使用主题中的属性,当主题和样式中的属性发生冲突时,样式的优先级要高于主题

自定义主题的代码:

<resource>
	<style name="grayTheme" parent="Theme.AppCompat.Light.DarkActionBar">
	<item name="android:background">#000000</item>
	</style>
</resource>

引用自定义主题代码:

<mainfest xmlns:android=......
	package="itcast.cn.dialog">
	<application
		...
		android:theme="@style/AppTheme">
		<activity
			android:name=".MainActivity"
			android:theme="@style/grayTheme">
			...
		</activity>
	</application>
</mainfest>

3. Activity

3.1 Activity 的创建

Activity是Andriod程序的四大组件之一,为用户提供可视化界面及操作,一个应用程序通常包含多个Activity,每个Activity负责管理一个用户界面,这些界面可以添加多个控件,每个控件负责实现不同功能

  • Android 开发的四大组件分别是
    • 活动(activity),用于表现功能;
    • 服务(service),后台运行服务,不提供界面呈现;
    • 广播接受者(BroadcastReceive),用于接收广播;
    • 内容提供者(ContentProvider),支持多个应用中存储和读取数据,相当于数据库 。

两种创建方式

  • 包名处点击右键选择New-Activity-Empty Activity选择,填写Activity信息,完成创建

  • 包名中点击右键选择New-Java Class 选项,填写Java类名,完成创建,在该类中继承AppCompatActivity,并在清单文件中进行注册,完成Activity的创建

3.2 Activity的生命周期

  • 启动状态:当Activity启动之后便会进入下一状态
  • 运行状态:当Activity处于屏幕最前端,可与用户进行交互
  • 暂停状态:Activity任可见,但无法获得焦点,用户对它的操作没有响应
  • 停止状态:Activity完全不可见,系统内存不足时会销毁该Activity
  • 销毁状态:Activity将被清除内存

生命周期方法:

生命周期方法用途
onCreate()在Activity即将可见时调用
onStart()在Activity即将可见时调用
onResume()Activity获取焦点时调用
onPause()当前Activity被其他Activity覆盖或锁屏时调用
onStop()Activity对用户不可见时调用
onRestart()Activity从停止状态再次启动时调用
onDestory()Activity销毁时调用
  • 手机横竖屏切换时,系统会根据AndroidMainfest.xml文件中Activity的configChanges属性值不同而调用相应的生命周期方法

  • 没有设置configChanges属性的值时:

    • 当由竖屏切换为横屏时,依次调用的方法依次是:

      onPause(),onStop(),onDestory(),onCreate(),onStart(),onResume()

  • 设置configChanges属性

<activity android:name=".MainActivity"
	android:configChanges="orientation|keyboardHidden|ScreenSize"

3.3 Activity的启动模式

1.任务栈

  • 任务栈:一种用来存放Activity实例的容器
  • 特点:先进后出
  • 操作:压栈和出栈

2. standard模式

standard模式是Activity的默认启动方式,每启动一个Activity就会在栈顶创建一个新的实例

3. singleTop模式

singleTop模式会判断要启动的Activity实例是否位于栈顶,如果位于栈顶则直接复用,否则创建新的实例

4. singleTask模式

singleTask模式下每次启动该Activity时,都会检查栈中是否存在当前Activity实例,如果存在则直接使用,并把当前Activity之上的所有实例全部出栈

5. singleInstance模式

singleInstance模式会启动一个新的任务栈来管理Activity实例,无论哪个任务栈中启动该Activity,该实例在整个系统中只有一个

6. 启动模式的设置

  • 通过AndrodMenifest.xml文件为Activity指定启动模式

    <activity android:name=".ActivityC"
    		  android:launchMode="singleTask"/>
    
  • 通过Intent中设置标志位(addFlags方法)来为Activity指定启动模式

    Intent intent=new Intent();
    intent.setClass(ActivityB.this,ActivityA.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    
  • 启动模式的设置

    • Intent.FLAG_ACTIVITY_NEW_TASK

      该标志位标识使用一个新的任务栈来启动一个Activity

    • Intent.FLAG_ACTIVITY_SINGLE_TOP

      该标志位表示使用singleTop模式来启动一个Activity

    • Intent.FLAG_ACTIVITY_CLEAR_TOP

      该标志位表示使用singleTask模式来启动一个Activity

3.4 Activity 之间的跳转

1. Intent

  • 意图,是程序中各组件进行交互的一种重要方式,它不仅可以指定当前组件要执行的动作,还可以在不同组件之间进行数据传递

  • 一般用于启动Activity、Service以及发送广播等,根据开启目标组件的方式不同,Intent可以被分为两种类型:显示意图和隐式意图

2. 显示意图

可以直接通过指定名称开启指定的目标组件

显示调用需要明确的指出被启动的对象的组件信息、包括包名和类名

Intent intent=new Intent(this,Activity02.class); //创建一个Intent对象,其中第一个参数位Context表示当前的Activity对象,第2个参数表示要启动的目标Activity
startActivity(intent);  //调用Activity的startActivity方法启动目标组件

3. 隐式意图

通过指定action和category等属性,系统在分析这些属性信息寻找目标Activity

需要Intent能匹配目标组件的IntentFilter中所设置的过滤信息.如果不匹配将无法启动目标Activity

Intent intent=new Intent();
intent.setAction("cn.itcast.START_ACTIVITY"); //设置action动作,当与清单文件中的action相匹配时,启动目标组件
startActivity(intent);
<activity android:name="cn.itcast">
	<intent-filter>
		<action android:name="cn.itcast.START_ACTIVITY"/> //设置action动作,当代码中的action与该action相匹配时启动该组件
		<category android:name="android.intent.category.DEFAULT"/>
	</intent_fliter>
</activity>

4. IntentFlier(过滤器)

  • 当发送一个隐式intent后,Android系统会将他和程序中的每一个组件的过滤器进行匹配,匹配的属性有action\data\category,需要这三个属性都匹配成功才能唤醒相应的组件

  • action:用于指定Intent对象的动作

    <intent-filter>
    	<action android:name="android:intent.action.EDIT"/>
    	<action android:name="android:intenr.action.VIEW"/>
    </intent-filter>
    

    那么只要Intent中的action能够和Activity过滤规则中的任何一个action相同即可匹配成功。

    在清单文件中为activity添加intent-filter标签时,必须添加action属性,否则隐式Intent无法开启该Activity

  • data:指定数据的URI或者数据MIME类型

    <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属性就匹配成功

  • catagory:用于Activity添加额外信息

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

    隐式Intent中声明的category必须全部能够与某一个IntentFilter中的category匹配才能算匹配成功

    IntentFilter中的category属性数量必须大于等于隐式Intent携带的category数量属性时,才能匹配成功

    如果一个隐式Intent没有携带category属性,那么他就可以通过任意一个Intent-filter的category匹配成功

3.5 Activity中的数据传递

1. 使用Intent提供的putExtra()方法

.putExtra

.getStringExtra

Intent intent=new intent(this,Activity02.class);
intent.putExtra("extra_data","Hello Activity02");//在Activity01中放入数据传送给Activity02
startAcivity(intent);

Intent intent=getintent();
String data=intent.getStringExtra("extra_data");//在Activity02中获取Activity01传递来的数据

2. 使用Bundle类传送数据

在MainActivity中将数据传递给ScendActivity

Intent intent=new Intent();
intent.setClass(this,SecondActivity.class); 
Bundle bundle=new Bundle(); //创建Bundle对象
bundle.putString("useName","sunhf"); //将用户名封装到Bundle对象中
intent.putExtra(bundle); //将Bundle对象封装到Intent对象中
startActivity(intent);

在SecondActivity中获取数据

Bundle bundle=getIntent().getExtra(); //获取Bundle对象
String accound=bundle.getString("userName"); //获取用户名

4. 数据存储

4.1 数据存储方法

Android中的5种数据存储方法

  • 文件存储:是一种常见的方法,与Java中的文件存储类似,都是通过I/O流的形式存储数据
  • SharedProferences:是Android提供的用来存储一些简单的配置信息的一种机制
  • SQLite数据库:Androd自带的一个轻量级数据库,支持基本SQL语法
  • ContentProvider:Android四大组件之一,可以将自己的数据分享给其他应用程序
    • Android 开发的四大组件分别是
      • 活动(activity),用于表现功能;
      • 服务(service),后台运行服务,不提供界面呈现;
      • 广播接受者(BroadcastReceive),用于接收广播;
      • 内容提供者(ContentProvider),支持多个应用中存储和读取数据,相当于数据库
  • 网络存储:是通过网络提供的存储空间来存储/获取数据信息

4.2 文件存储

  • 分为内部存储和外部存储

    内部存储外部存储
    存储位置将数据以文件的形式存储到应用种将数据以文件的形式存储到外部设备上
    存储路径data/data//目录下mnt/sdcard/目录下,使用getExternalStoageDirectory()获得根目录
    其他应用操纵该文件时需要设置权限不用设置权限,会被其他应用共享
    删除文件当应用被卸载时,该文件也会被删除该文件可在本应用外删除,使用前需要确认外部设备是否可用
    操作数据通过openFileOutput()方法和openFileInput()方法获取FileOutputStream和FileInputStream操作对象直接使用FileOutputStream和FileInputStream操作对象

1. 内部存储

FileOutputStream fos=openFileOutput(String name,int mode);
FileInputStrean fis=openFileInput(String name);
  • mode取值

    • MODE_PRIVATE:该文件只能被当前程序读写
    • MODE_APPEND:该文件内容可以追加
    • MODE_WORLD_READABLE:该文件的内容可以被其他程序读
    • MODE_WORLD_WRITEABLE:该文件的内容可以被其他程序写
      • Android系统有一套自己的安全模型,默认情况下任何应用创建的文件都是私有的,其他程序无法访问。除非在文件中指定了操作模式为MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE。如果希望外部文件能被其他程序进行读写操作。需要同时指定MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE权限。
  • 写入

    String fileName="data.txt"; //文件名称
    String content="hello";//保存数据
    FileOutputStream fos=openFileOutput(fileName,MODE_PRIVATE);
    fos.write(content.getBytes());
    fos.close;
    
  • 读取

    String content="";
    FileInputSream fis=null;
    fis=openFileInput("data.txt"); //获得文件输入流对象
    byte[] buffer=new byte[fis.available()];
    fis.read(buffer);
    content=new String(buffer);
    fis.close;
    

2. 外部存储

由于外部设备可能被移除,丢失或处于其他状态,因此在使用外部设备之前必须使用

**Environment.getExternalStorageState()**方法来确认外部设备是否可用。当外部设备可用并且具有读写权限时,那么就可以通过FileInputStream、FileOutputStream对象来读写外部设备中的文件。

4.3 XML解析

三种解析方法

解析方法补充缺点
DOM解析将XML文件中所有内容以DOM树形式存放到内存中,支持删除,修改等功能消耗内存大
SAX解析逐行扫描XML文件,读取文件的同时即可进行解析处理,不必等到文件加载结束无法进行增、删、改等操作
PULL解析一个开源的Java项目,既可以用于Android应用,也可用于JavaEE程序,Android中以及集成了PULL解析器
  • XmlPullParser:PULL解析器类

    XmlPullParser parser=Xml.newPullParser();//获取PULL解析器
    xmlPullParser.setInput(is,"UTF-8");//设置解析器参数
    int type=xmlPullParser.getEventType();//获得事件类型
    

4.4 JSON解析

  • 对象标识法,是一种轻量级的数据交换格式
  • JSON是基于纯文本的数据格式,他可以传输String,Number,Boolean类型的数据,也可以传输数组,或者Object对象
  • JSON文件的扩展名为.json
  • JSON分为JSON对象和JSON数组两种数据结构

两种解析方式

1. org.json

  • 例如要解析是json数据如下

    {"name":"xiaowang","age":18,"married":forse} //json1
    
    JSONObject jsonObj=new JSONObject(json1);
    String name=jsonObj.optString("name");
    int age=jsonObj.optInt("age");
    booleam married.optBoolean("married");
    
  • 使用org.json解析JSON数组

    例如要解析的JSON数据如下

    [111,11,1] //json2
    
    JSONArray jsonArray=new JSONArray(json2);
    for(int i=0;i<jsonArray.length();i++)
    {
    	int age=jsonArray.optInt(i);
    }
    

2. Gson

使用Gson库之前,先要将gson.jar添加到项目中,并创建JSON数据对应的实体类Person

  • 使用Gson解析json对象

    Gson gson=new Gson();
    Person person=gson.fromJson(json1,Person.class);//Person.class与json对应的实体类
    
    
  • 使用Gson解析json数组

    Gson gson=new Gson();
    Type listType=new TypeToken<List<Integer>>(){}.getType;//指定数据类型
    List<Integer>ages=gson.fromJson(json2,listType);
    
    

4.5 SharedPreferences

  • 是Android平台上一个轻量级的存储类,用于存储应用程序的配置参数,如文件名、密码等
  • 通过key/value(键值对)的形式将数据保存到XML文件中,文件存放在/data/data//shared_prefs目录下
  • value值只能是 float\int\long\boolean\String\StringSet 类型数据

1. 将数据存入ShardPreferences中

getShardPreferences(name,mode)
//第一个参数用于指定该文件的名称,名称不用带后缀
//第二个参数指定文件的操作模式

文件的MODE:

  • MODE_PRIVATE:该文件只能被当前程序读写
  • MODE_APPEND:该文件内容可以追加
  • MODE_WORLD_READABLE:该文件的内容可以被其他程序读
  • MODE_WORLD_WRITEABLE:该文件的内容可以被其他程序写
    • Android系统有一套自己的安全模型,默认情况下任何应用创建的文件都是私有的,其他程序无法访问。除非在文件中指定了操作模式为MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE。如果希望外部文件能被其他程序进行读写操作。需要同时指定MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE权限。
ShardPreferences sp=getShardPreferences("data",MODE_PRIVATE);//得到ShardPreferences对象
ShardPreferences.Editor editor=sp.edit(); //获得ShardPreferences编译器
editor.putString("name","王"); //使用编译器存储数据
editor.putInt("age",18);
editor.commit(); //提交保存数据

2. 读取和删除数据

  • 读取数据

    ShardPreferences sp=getShardPreferences("data",MODE_PRIVATE);
    String data=sp.getString("name","");
    
    
  • 删除数据

    editor.remove("name"); //根据键 删除数据
    editor.clear();//删除所有数据
    editor.commit;
    
    

    5. SQLite数据库

5.1 简介

SQLite特点:

  • SQLite是一个轻量级数据库,占用资源非常低
  • SQLite是遵守ACID的关系型数据库管理系统
    • 原子性
    • 一致性
    • 隔离性
    • 持久性
  • SQLite保存数据时,支持NULL(零),INTEGER(整型),REAL(浮点数字),TEXT(字符串文本)和BLOB(二进制对象)五种数据类型

5.2 数据库的创建

1. 创建数据库

SQLiteOpenHelper类:是SQLiteDatabase的一个帮助类,用于数据库创建和版本的更新,一般是建立一个类去继承他,并实现他的onCrete()和onUpgrade()

方法名方法描述
SQLiteOpenHelper()构造方法
onCreate()创建数据库时调用
onUpgrade()版本更新时调用
getReadableDatabase()创建或打开一个只读数据库
getWriteableDatabase()创建或打开一个读写数据库

5.3 数据库的使用

1. 添加数据

(long)insert(String table,String nullCoiumnHack,ContentValues values)
返回:添加的记录条数,不成功则返回-1
参数:数据表名;插入某个字段值为空时,设置字段值为null;键值对形式存储的对象
public void insert(String name,String sNumber){
//获取可读写对象
	SQLiteDatabase db=helper.getWriteableDatabase(); 
//创建ContentValues对象并将数据添加到对象中
	ContentValues values=new ContentValues(); 
	values.put("name",name);
	values.put("age",sNumber);
//调用insert()将数据添加到数据库中
	long id=db.insert("information",null,values);
	db.close();
}

2. 修改数据

(int)update(String table,ContentValues values,Sting whereClause,String[] whereArgs)
返回:更新的记录有几条
参数:表名;更新的值:ContentValues对象;定位条件——占位符;条件的值
publis int update(String name,String sNumber){
	SQLiteDatabase db=helper.getWriteableDatabase();
	ContentValues values=new ContentValues();
	values.put("sNumber",sNumber);
	int number=db.update("information",values,"name=?",now String[]{name});
	db.close;
	return number;
}

3. 删除数据

(int)delete(String table,String whereClause,String[]whereArgs)
返回:被删除的记录条数
参数:表名;条件;条件的值
public int delete(String sNumber){
	SQLiteDatabase db=helper.getWritezbleDatabase();
	int number=db.delete("information","sNumber=?",new String[]{sNumber});
	db.close();
	return number;
}

4. 查询数据

(Cursor)query(String table,String() columns,String selection,String[]selectionArgs,String groupBy,String having,String orderBy)
返回:结果集

cursor(游标)

方法名称方法描述
getCount()总记录条数
isFirst()判断是否是第一条记录
isLast()判断时候是最后一条记录
moveToFirst()移动到第一条记录
moveToLast()移动到最后一条记录
move(int offset)移动到指定的记录
moveToNext()移动到上一条记录
moveToPrevious()移动到吓一条记录
getColmnsIndex()获得指定列的索引值

5. 事务

  • 数据库事务是一个对数据库执行工作单元,是针对数据库的一组操作,他可以由一条或者多条SQL语句组成
  • 事务是以逻辑顺序完成的工作单位或序列,可以由用户手动操作完成,也可以由数据库程序自动完成。
//开启数据库事务
db.beginTransation();
//设置数据库标志位成功,当事务结束时,提交事务
}
catch(Exception e){
	Log.i("事务处理失败",e.toString());
}
//关闭数据库事务
db.close();

5.4 数据展示控件

1. ListView 的简单使用

  • ListView以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示
属性名称功能描述
android:listSelector当条目被点击后,改变条目的背景色
android:divider设置分割线的颜色
android:dividerHeight设置分割线的高度
android:scrollbars是否显示滚动条
android:fadingEdge去掉上下的黑色阴影

2. 常用数据适配器(Adapter)

  • 数据适配器时数据和视图之间的桥梁,类似于一个转换器,将复杂的数据转化成用户可以接收的方式
  • 常用的数据适配器
    • BaseAdapter
    • SimpleAdapter
    • ArrayAdapter

3.BaseAdapter

BaseAdapter(抽象类)即基本的适配器,自定义适配器继承BaseAdapter,需要实现四个方法

方法名称功能表述
public int getCount()得到Item条目的总数
public Object getItem(int position)根据postion得到某个Item的对象
public long getItemId(int position)根据position得到某个Item的id
public View getView(int position,View convertView,ViewGroup)得到相应position对应的Item视图,position是当前Item的位置,convertView用于复用旧视图

4. SimpleAdapter

SimpleAdapter继承自基本适配器,实现了BaseAdapter的四个抽象方法并进行了封装

public SimpleAdapter(Context context,List<?extends Map<String,?>>data,int resource,String[]from,int[] to)

5. ArrayAdapter

ArrayAdapter也是基本适配器的子类,通常用于适配TextView控件

6. ListView 的优化

两种优化方法

  • 复用convertView
  • 使用ViewHolder类

6. BroadcastReceiver(广播接收者)

Android 开发的四大组件分别是

  • 活动(activity),用于表现功能;
  • 服务(service),后台运行服务,不提供界面呈现;
  • 广播接受者(BroadcastReceive),用于接收广播;
  • 内容提供者(ContentProvider),支持多个应用中存储和读取数据,相当于数据库 。

6.1 广播接收者简介

  • 广播接收者是通过Binder机制在AMS中进行注册的

  • 广播接收者是通过Binder机制向AMS发送广播

  • AMS查找符合相关条件的广播接收者,将广播发送到相应的消息循环队列中

  • 执行消息循环时获取到此广播,会回调广播接收者中的onReceive()方法并在该方法中进行相关处理

  • Android系统中内置了很多广播,例如手机开机完成

  • 为了监听来自系统或应用程序的广播事件,Android系统提供了BroadcastReceiver组件

  • 当Android系统中产生一个广播事件时,可以有多个对应的广播接收者接收并进行处理

6.2 广播接收者入门

创建
在onReceive()中实现操作

public class MyReceiver extends BoastcastReceiver{
	public MyReceiver(){
	}
	public void onReceiver(Context context,Intent intent){
	//实现广播接收者的相关操作
		throw new UnsupportedOperationException("Not yet implemented");
	}
}

静态注册广播:只要设备处于开启状态,广播接收者就能接收到广播

<receiver
	android:name=".MyReceiver"
	android:enable="true"
	android:exported="true">
</receiver>

对于应用程序监听SMS Intent广播,首先需要添加RECEIVEE_SMS权限

<uses-permission android:name="android.permission.RECEIVE_SMS"/>
protected void onCreate(Bundle savedInstanceState){
	super.onCreate(savedInstanceState);
	MyReceiver receiver=new Myreceiver();
	//实例化过滤器并设备要过滤的广播
	String action="android.provider.Telephony.SMS_RECEIVED";
	IntentFilter intentFile=new IntentFile(action);
	//注册广播
	registerReceiver(receiver,intentFile);
}
protected void onDestory(){
	super.onDestory();
	//当Activity销毁时,取消注册
	unregisterReceiver(receiver);
}

6.3 自定义广播

  • 当系统提供的广播不能满足实际需求时,可以自定义广播,同时需要编写对应的广播接收者

  • 当自定义广播发送消息时,会存储到公共消息区,而公共消息区中如果存在对应的广播接收者,就会及时接收这条消息

自定义广播

Android8.0+后,限制隐式广播-

  • 广播接收者静态注册的情况下,发送隐式广播需要设置标志位突破隐式广播限制

    Intent intent=new intent();
    intent.addFlags(0x01000000);
    intent.setActin("help,help,help");
    sendBroadcast(intent);
    
  • 广播接收者静态注册的情况下,发送显示广播

    Intent intent=new Intent();
    intent.setComponent(new ComponentName("广播接收者的包名","广播接收者的完整类名"));
    sendBroadcast(intent);
    
  • 动态注册广播接收者

    Intent intent=new Intent();
    intent.setAction("help,help,help");
    sendBroadcast(intent);
    

6.4 广播类型

  • android提供了两种广播类型,有序广播和无需广播

  • 有序广播:按照接收者的优先级结束,只有一个广播接收者能接收消息,在此广播接收者中逻辑执行完毕后,才会继续传递。

    //数值越大,优先级越高
    <intent-filer android:prority="100"/>
    
//动态注册MyReceiver广播
Myreceiver one=new MyReceiver();
IntentFlier filer=new IntentFiler();
filter.setPriority(100);

发送有序广播:sendOrderedBroadcast()

中断广播:abortBroadcast()

  • 无序广播即为我们平时经常使用的广播,其主要是通过public abstract void sendBroadcast (Intent intent)方法进行发送,并通过intent传递数据。 无序广播不可以被拦截,不可以被终止,不可以被修改,无序广播任何接收者只要匹配条件都可以接收到,无优先级问题。

7. Service

7.1 服务的创建

Android 开发的四大组件分别是

  • 活动(activity),用于表现功能;
  • 服务(service),后台运行服务,不提供界面呈现;
  • 广播接受者(BroadcastReceive),用于接收广播;
  • 内容提供者(ContentProvider),支持多个应用中存储和读取数据,相当于数据库 。

service是android四大组件之一,,能够在后台长时间执行操作且不提供用户界面的应用程序组件,service可以和其他组件进行交互,一般是由Activity启动,但是并不依赖与活动。

当活动的生命周期结束时,Service任然会继续运行,直到自己的生命周期结束为止

Service通常被称为“后台服务”,具体是指其本身的运行不依赖于用户可视的UI界面,此外,它的应用场景还有两个,后台运行和跨进程访问。

1. 服务的创建

  • 服务的创建和广播接收者类似,同样在程序包名上点击右键选择new service ,在弹出窗口输入服务的名称即可完成创建

  • 服务创建完成后,android studio会自动在AndroidMainfesr.xml中对服务进行注册

  • 自动创建java类继承Service类,来创建服务

  • 若采用自行创建java类继承Service类的方式创建服务,则需要手动在清单文件中进行注册

    清单文件

<mainfest xmlns:android="http...">
	<application..>
		<service
			android:name="MyService"	//服务的路径
			android:cnabled="true"		//表示是否能被实例化
			android:exported="true">    //表示该服务能够被其他应用程序组件调用
		</service>
	</application>
</mainfest>

7.2 服务的生命周期

7.3 服务的启动方式

  • 服务的启动方式
启动方式终止方法
startService()需要自身调用stopSelf()方法或者其他组件调用stopService()方法,服务才能停止
bindService()需要调用onUnbind()方法接触绑定之后才会销毁

使用不同的方法启动服务,其生命周期也是不同的

1. startService方法启动

startService() 方法启动服务,服务会长期在后台运行,并且服务的状态与开启者的状态没有关系,即启动服务的组件已经被销毁,服务会依然运行

开启服务
Intent intent=new Intent(this,MyService.class);
startService(intent);
关闭服务
Intent intent=new Intent(this,MyService.class);
stopService(intent);

2. bindService方式启动

通过bindService()方法启动服务时,服务会和组件绑定,当服务中的onUnbind()方法调用时,这个服务就会被销毁

绑定服务
Intent intent=new Intent(this,MyService);
//Intent service用于指定要启动的SC,
//ServiceConnection conn用于监听调用者与SC之间的连接状态,
//int flags用于绑定时是否自动创建Service
bindService(Intent service,ServiceConnection conn,int flags)

ServiceConnection conn:监听器,监听调用者与Service之间的连接

class MyServiceConn implements ServiceConnection{
	public void onServiceConnected(ComponentName compoentName,IBinder iBinder){}
	public void onServiceDisconnected(ComponentName componentName){}
}

int flags用于绑定时是否自动创建Service,0表示不自动创建,BIND_AUTO_CREATE表示自动创建

解除绑定
unbindServce(conn);

为什么有了startService()还要BindService()?

为了调用服务里的方法

​ 定义IBinder对象

​ 在onBind()方法内返回IBinder对象

​ bindService()绑定服务,获取IBinder对象,调用服务里方法

3. 混合方式开启服务

startService()方法开启bindService()方法开启
一旦开启,未调用stopService()关闭服务,会一直在后台运行与调用组件同生共死,绑定服务后,返回Binder对象,可调用服务里的方法

混合开启服务的步骤:

  • startService():开启服务,保证服务可以长期在后台运行
  • bindService():绑定服务,获取”IBinder“对象
  • unbindService():解绑夫区,但服务未销毁

7.4 服务的通信

服务方式
本地服务通信本地服务通信是指应用程序内部的通信,需要使用IBinder对象进行本地服务通信
远程服务通信远程服务通信是指两个应用程序之间的通信,远程服务通信是通过AIDL实现的
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值