1,Service组件的用法
Service代表可执行的程序
区别:Service一直在后台运行,没有用户界面,具有自己的生命周期
开发Service的步骤:
先开发一个Service子类
在AndroidManifest.xml文件配置该Service
配置时通过元素指定它可以被哪些Intent启动
Android系统本身提供了大量了Service组件
Service组件时可执行的程序,有足迹的生命周期
(1)创建
①定义一个继承Service子类
②在AndroidManifest.xml文件中配置Service
(Service与Activity都是从Context派生出来的,都可以调用Context的getResources()、getContentResolver()方法)
Service的一系列生命周期方法:
IBinder onBind(Intent intetn),子类必须实现,应用程序通过该对象与Service组件通信
void onCreate(),第一次被创建后立即回调
void onDestroy(),关闭之前回调
void onStartCommand(Intent intent,int flags,int startId),早期的onStart(),每次客户端调用startService(Intent)方法启动该Service时都会回调
boolean onUnbind(Intent intent),绑定的所有客户端都断开连接时回调
public class FirstService extentds Services
{
//必须实现的方法
public IBinder onbind(Intent arg)
{
{
//Service被创建时回调
public void onCreate()
{
}
//Service被启动时回调该方法
public int onStartCommand(Intent intetn ,int flags,int satrtId)
{
}
//Service被关闭前回调
public void onDestroy()
{
}
}
(2)配置
接下载在AndroidManifest.xml文件中配置
配置Service使用<service…/>元素,同时可以配置<intent-filter…/>子元素说明该Service可被那些Intent启动
<service android:name=".FirstService">
</service>
注意:无需像Activity指定android:label实行,因为Service没有界面,总是位于后台运行
▲在Android系统中运行Service的两种方式
Ⅰ,通过Context的starService()方法,此时,访问者与Service之间没有关联,即使访问者对出了,Service也依然运行
Ⅱ,通过Context的bindService()方法,此时,访问者与Service绑定在一起,访问者退出则Service终止
(3)启动与停止
//创建启动Service的Intent
final Intent intent = new Intetn(this,FirstService.class);
//启动指定Service
startService(intent);
//停止指定Service
stopService(intent);
注意:每次Service被创建会回调onCreate()方法,每次Service被启动会回调onStartCommand()方法,多次启动一个已有的Service组件不会回调onCreate()方法,但会回调onStartCommand()方法。
(4)绑定本地Service
Service和访问者需要通过使用bindService()和unbindService()方法启动和关闭Service,才能进行方法调用和狡猾数据。
bingService(Intent service,ServiceConnection conn,int flags)l
service:通过Intent指定要启动的Service
conn:监听访问者与Service之间的连接情况
flag:指定绑定时是否自动创建Service
🔺其他程序组件通过IBinder对象与Service组件进行实时通信,当其他程序组件绑定该Service时,Service将会把IBinder对象返回给其他程序组件
开发时,通常采用继承Binder的方式实现自己的IBinder对象
public class BindService ectends Service
{
//定义onBinder方法所返回的对象
private MyBinder binder=new MyBinder();
//通过继承Binder来实现IBinder类
public class MyBinder extends Binder
{
}
//实现onBind()方法,必须实现
public IBinder onBind(Intent intent)
{
return binder;//这个IBinder对象会传给其他程序组件用于通信
}
}
public class MainActivity extends Activity
{
//保持所穷的那个的Service的IBinder对象
BindService.MyBinder binder;
//定义一个ServiceConnection对象
pvivate ServiceConnectin conn=new ServiceConnection()
{
//🔺当Activity与Servicy连接成功时回调该方法;且吧IBinder对象穿过来
public void onServiceConnectied(ComponentName name.IBinder service)
{
//获取Service的onBind方法返回的MyBinder对象
binder=(BindService.MyBinder)service;
}
//当Activity与Service断开连接时回调
public void onServiceDisconnected(ComponentName name)
{
}
};
}
当程序调用unbindService()方法接触对某个Service的绑定时,系统先回调onUnbind()方法,在回调onDestroy()方法
多次调用bindService()方法不会重复绑定(startService()方法会重复启动)
2,SharedPreferences存储数据
保存的数据主要是简单类型key-value对
SharedPreferences接口主要负责读取应用程序的Preferences数据,
▲函数
boolean contains(String key):判断SharedPreferences是否包含特定key数据
abstract Map<String,?> getAll():获取SharedPreferences数据里全部的key-value对
boolean getXXX(String key,xxx defValue):获取SharedPreferences数据里指定key对象的value
SharedPreferences接口没有写入数据的能力(通过SharedPreferences的内部接口Ediror写入)
🔺SharedPreferences调用edit()方法获取所对应的Ediror对象
▲内部类Ediror的方法
SharedPreferences.Edirot clear():清空SharedPreferences的所有数据
SharedPreferences.Edirot putXXX(String key ,xxx value):向SharedPreferences存入指定key对应得数据
SharedPreferences.Ediror remove(String key):删除SharedPreferences里指定key对应的数据项
boolean commit():当Ediror编辑完成后,使用该方法提交修改
注意:SharedPreferences是一个接口库,只能通过Context提供的getSharedPreferences(String name,int mode)方法获取SharedPreferences实例
mode取值:
Conrext.MODE_PRIVARE:只能本应用程序读写
SharedPreferences preferences;
SharedPreferences.Edirot editor;
//获取只能本应用程序读写的SharedPreferences对象
preferendes=getSharedPreferences("",MODE_PRIVATE);
editor=preferences.edit();
//使用SharedPreferences对象读数据
String time=preferences.getString("thime",null);
//使用SharedPreferences.Edirot对象写输入
edirot.putString("time","待保存的值“);
SharedPreferences数据总是保存在/data/data//shared_prefs
SharedPreferences数据总是以XML格式保存
3,SQLite数据库
SQLite数据库知识一个文件
当应用程序创建或打开一个SQLite数据库时,只是打开一个文件准备读写
方法:
SQLiteDatabase提供的打开一个文件对应的数据库的静态方法
static SQLiteDatabase openDatebase(String path,SQLiteDatavase.CursorFactory factory ,int flags):打开path文件所达标的SQLite数据库
static SQLiteDatabase openOrCreateDatabase(File file/String path,SQLiteDatabase Cursor,Factory factory):打开或创建file文件或path文件所代表的SQLite数据库
在实际项目中很少使用SQLiteDatabase的方法打开数据库,通常采用继承SQLiteOpenHelper开发子类,通过子类的getReadableDatabase()、getWritableDatabase()方法打开数据库
4, Intent的各个属性
Intent封装了程序想要启动程序的意图,还可以用于与被启动组件交换信息
Android的三个重要组件:Activity、Service、BroadcastReceiver都是依靠Intent启动
▲启动不同组件的方法
Activity:
startActivity(Intent intent);
startActivityForResult(Intent intent,int requestCode);
Service:
ComponentName startService(Intent service);
boolean bindService(Intent service ,ServiceConnection conn ,int flags);
BroadcastReceiver:
略
(1)Component属性
Component属性需要接受一个ComponentName对象,使用构造函数ComponentName(),创建ComponentName需要指定包名和类名确定唯一的一个组件类
使应用程序根据给定的组件类启动特定的组件
Intent对应的三个方法:
setClass(Contextpackage Context, Class<?> cls):设置该Intent将要启动的组件对应的类
setClassName(Context/String packageContext,String className):同上
指定Component属性的Intent明确了将要启动的组件,称显示Intent;
美哟指定Component属性的Intent,称隐式Intent
//创建一个ComponentName对象
ComponentName comp=new ComponentName(MainActivity.this,SecondActivity.class);
Intent intent = new Intent();
//为Intent设置Component属性
intent.setComponent(comp);
startActivity(intent);
//SecondActivity类
//获取该Activity对应的Intent的Component属性
ComponentName comp=getIntent().getComponent();
comp.getPackageNeme();
com.getClassName();
(2)Action、Category属性与intent-filter配置
Intent的Action、Category属性的值都是一个普通的字符串
Action:代表该Intent所要完成的一个抽象”动作“(但Action不管动作具体由哪个组件完成,取决于<intent-filter …/>配置,只要某个Activity的<intent-filter…/>配置中包含了该动作就,该Actvitiy就有可能被启动)
Category:用于为Action增加额外的附加类别信息
通常二者结合使用
//第一个Activity
//创建Intent对象
Intent intent =new Intent();
//为Intent设置Action属性(属性值就是一个普通字符串)
intent.setAction(MainActivity.LICHUANG);
startActivity(intent);
<intent-filter…/>元素是AndroidManifest.xml文件中<activity…/>元素的子元素(<activity…/>元素用于应用程序配置Activity,<activity…/>子元素<intent-filter…/>则用于配置该Activity所能”响应”的Intent)
附加:
<intent-filter…/>通常可包含:
0~N个<action…/>子元素
0~N个<catefory…/>子元素
0~1个<data…/>子元素
当<activity…/>元素的<intent-filter…/>子元素里包含多个<action…/>子元素时,表明该Activity能响应Action属性值为其中任意一个字符串的Intent
程序创建Inten时,Intent默认启动Category属性值为Intent.CATEGORY_DEFAULT常量的组件
//被启动的Activity对应的配置
//<intent-filter.../>元素中
<action android:name="org.li.intent.action.LICHUANG"/>
<category android:name=android.intent.catefory.DEFAULT"/>
注意:
一个Intent对象最多只能包括一个Action属性,程序可以调用Intent的setAction(String str)设置Action属性值
一个Intent对象可以包括多个Category属性,程序可以调用Intent的addCategory(String str)方法添加Category属性
String action=getIntent().getAction();
Set<String> cates=getIntent().getCategories();
Action、Category可以启动Android系统的自带的程序组件——只要权限允许
(3)Data、Type属性与intent-filter配置
Data属性通常用于向Action属性提供操作的数据,接受一个uri对象
Type属性用于指定该Data属性所指定Uri对应的MIME类型,(这种MIME类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串)
附:
Uri对象的形式
▲scheme://host:post/path
注意:
Data属性和Type属性会相互覆盖,后设置的会覆盖先设置的
如果需要同时保存,调用Intent的setDataAndType()方法
🔺AndroidManifest.xml文件中<data…/>元素
(声明Data和Type属性都是通过<data…/>元素)
<data android:mimeType="" //声明该组件所能匹配的Intent的Type属性
android:scheme="" //Data属性的scheme部分
android:host="" //Data属性的host
android:port=""
android:path=""
android:pathPrefix=""Data属性的path前缀
android:pathPattern=""//Data属性的path字符串模板
匹配规则:
Intent的Type属性必须与对应组件<intent-filter…/>元素的<data…/>子元素的mimeType属性必须相同
▲Intetn的Data属性大于等于<data…/>子元素的属性(如果<data…/>子元素只有android:port属性,没有指定android:host属性,那么android:port/path属性不会起作用——就是必须的有主机,要不路径和端口都没用)
Intent intent=new Intent();
intent.setData(Uri.parse("lee://www.lichuang.org:123/test"));
startActivity(intent):
🔺使用Action、Data属性启动系统Activity
(4)Extra属性
通常用于在对各Action之间进行数据交换
属性值应该是Bundle对象
5,创建、配置、启动、关闭Activity的方法
Activity应用的多个Activity组成Activity栈,当前活动的Activity位于栈顶
(1)创建
建立Activity需要继承Activity基类,或继承Activity的子类
Activity类间接或直接地继承了Contenxt、ContenxtWrapper、ContextThemeWrapper等基类
(2)配置
只要为<application,./>元素添加<activity…/>子元素即可配置Activity
<activity android:name=".SampleActivity"//指定该Activity的实现类的类名
android:icon="@drawable/picture.png"//对应得图标
android:label="@String/labelName"//标签
android:exported="true"//是否允许被其他应用调用
android:launchMode="">//加载模式
</activity>
(3)启动、关闭Activity
Activity启动其他Activity的方法:
startActivity(Intent intent)
startActivityForResult(Intent intent ,int requestCode):以指定请求码启动Activity,程序将会获取新启动的Activity返回的结果(需要通过重写onActivityResult())
关闭Activity的方法:
finish()
finishActivity(int requestCode):结束以startActivityForResult(Intent intent,int requestCode)方法启动该的Activity
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);//启动了人家
finish();//结束了自己
6,Activity之间交换数据
Intent提供了多个从在的方法携带数据:
putExtras(Bundle data):向Intent中放入需要携带的数据包
Bundle getExtras():取出Intnet中携带的数据包
putExtra(String name,XXX value):向Intent中按key-value对的形式存入数据
getXXXExtra(String name):从Intent中按key取出指定类型的数据
Bundle是一个数据携带包,包含的方法:
putXXX(String key,XXX data):向Bundle中放入Int,Long等个各种类型的数据
putSerializable(String key,Serializable data):放入可序列化的对象
getXXX(String key):取数据
getSerializable(String key,Serializable data):取可序列化对象
//创建一个Bundle对象
Bundle data=new Bundle();
data.putSerializable("person",p);
//创建一个Intent
Intent intent=new Intent(MainActivity.this,ResultActivity.class);
intent.putExtras(data);
//启动intent
startActivity(intent);
//获取启动该Activity的Intent
Intent intent=getIntent();
//直接通过Intent取出它所携带的Bundle数据包中的数据
Preson p=(Person)intent.getSerailizableExtra("person");
▲启动其他Activity并返回结果
Ⅰ当前Activity需要重写onActivityResult(int requestCode,int resultCode,Intent intent),当被启动的Activity返回结果时,该方法被触发
Ⅱ被启动的Activity需要调用setResult()方法设置处理结果
//创建需要对应于目标Activity的Intent
Intent intent=new Intent(MainActivity.this,OtherActivity.class);
//启动指定Activity并等待返回的结果,其中0是请求码,用于表示请求
startActivityForResult(intent.0);
🔺重写onActivityResult()方法,当被启动的Activity返回结果时,会被回调来获取指定Activity返回的结果
//代码略
在otherActivity中设置结果 码,并设置结果之后退回的Activity
//获取启动该Activity之前的Activity对应的Intent
Intent intent=getIntent();
intent.putExtra();
otherActivity.this.setResult(0,intent);
7,Android中事件处理的基本原理
▲基于监听的事件处理(为Android界面组件绑定特定的事件监听器,界面布局文件中为UI组件的android;onClick属性指定事件监听方法)
▲基于回调的事件处理(重写Android组件特定的回调方法或重写Activity的回调方法)
(1)基于监听的事件处理
Event Source(事件源):事件发生的场所,通常就是各个组件
Event(事件):事件封装了界面组件发生的特定事件
Event Listener(事件监听器):负责监听事件源所发生的事件,并对分钟事件做出相应的响应
//获取应用程序中的bn按钮
BUtton bn=(Button)fingViewById(R.id.bn);
//为按钮绑定事件监听器
bn.setOnclickListener(new MyClickListerener());
//定义一个单击事件的监听器
class MyClickListener implements View.OnClickListener
{
//实现监听器类必须实现的方法,该方法作为事件处理器
public.void onClick(View v)
{
}
}
基于监听的事件处理模型编程步骤:
①获取普通界面组件(事件源),也就是被监听对象
②实现时间监听器类,该监听器类是一个特殊的java类,必须实现一个XXXListener接口
③调用事件源的setXXXListener方法将时间监听器对象注册给普通组件(事件源)
当事件源发生指定事件时,Android会触发事件监听器,由事件监听器调用相应事件处理器处理事件