1.start开启服务的生命周期(重点)
startService方法开启服务,stopService停止服务;
* 服务的特点:
服务被创建时调用onCreate、onStartCommand;
服务只能被创建一次,可以开启多次onStartCommand;
服务只能被停止一次; 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
* 生命周期的方法:
onCreate:服务被创建的时候调用这个方法;
onStartCommand :开启服务
onDestroy:销毁服务
2.bind方式开启服务的生命周期(重点)
bindService绑定服务:onCreate、onBind方法;
unBindService解除绑定:onUnbind、onDestroy方法;
特点:
1.服务第一次被绑定的时候,会创建服务对象,调用onCreate初始化服务,调用onBind方法绑定服务;
2.服务只能被帮定一次;
3.服务只能被解除绑定一次,多次解除绑定会抛出异常;
生命周期:
onCreate:初始化;
onBind:绑定服务;
onUnbind:解除绑定;
onDestroy销毁服务;
3.为什么要引入bindservice的API?
目的:无论是startService还是bindService都不能得到一个服务对象,而且直接创建一个服务对象,都不能直接调用服务的业务逻辑方法。
解决办法:在服务类里面创建一个中间人对象,当服务绑定成功时使用onBind方法返回一个中间人对象, 在activity里面得到中间人对象,然后让中间人调用服务的业务逻辑方法,从而达到间接调用服务业务逻辑方法的目的。
4.绑定服务调用服务方法的过程
步骤:
1.在服务类里面创建一个中间人,中间人里面写一个方法,让它调用服务的业务逻辑方法;
2.在activity中绑定服务成功后返回一个中间人对象;
3.在activity中调用中间人的方法;
代码:
1、在服务类里面创建一个中间人,中间人里面写一个方法,让它调用服务的业务逻辑方法
package com.qaa.bindservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class TestService extends Service {
public void methodInService(){
Toast.makeText(this, "===methodInService===", 0).show();
}
/**
* 绑定服务的时候调用这个方法
*/
@Override
public IBinder onBind(Intent intent)
{
System.out.println("==========onBind===========");
//服务绑定成功后返回一个中间人对象
return new MyBinder(); }
/**
* 中间人,是IBinder类型的
* @author Administrator
* */
public class MyBinder extends Binder{
public void callMethodInService(){
//调用服务的业务逻辑方法
methodInService();
}
}
/**
* 解除绑定服务的时候调用这个方法
*/
@Override
public boolean onUnbind(Intent intent) {
System.out.println("==========onUnbind===========");
return super.onUnbind(intent); }
@Override
public void onCreate() {
System.out.println("==========onCreate==========="); super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("==========onStartCommand===========");
return super.onStartCommand(intent, flags, startId); }
@Override
public void onDestroy() {
System.out.println("==========onDestroy===========");
super.onDestroy();
}
}
2.在activity中绑定服务成功后返回一个中间人对象;
/**
* 服务绑定成功时调用这个方法
*/ @Override public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyBinder)service; }
3.在activity中调用中间人的方法;
public void call(View view) {
//调用中间人的方法,达到间接调用服务的业务逻辑方法的目的
myBinder.callMethodInService();
}
5.绑定服务抽取接口(重点)
接口:对外暴露功能,隐藏实现的细节;
步骤:
1.写个接口类,添加一个方法;
2.在服务类里面让中间人实现这个接口类,实现接口里面的方法,在实现的方法里面调用服务的业务逻辑方法;
3.在activity中绑定服务成功时得到接口类型的中间人;
4.在activity中调用接口类型的中间人的方法;
代码:
1.写个接口类,添加一个方法;
public interface IService {
public void callMethodInService();
}
2.在服务类里面让中间人实现这个接口类,实现接口里面的方法,在实现的方法里面调用服务的业务逻辑方法;
/**
* 中间人,是IBinder类型的
* @author Administrator
* */
private class MyBinder extends Binder implements IService{
@Override
public void callMethodInService() {
//调用服务的业务逻辑方法
methodInService();
}
}
3.在activity中绑定服务成功时得到接口类型的中间人;
/**
* 服务绑定成功时调用这个方法
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (IService)service;
}
4.在activity中调用接口类型的中间人的方法;
public void call(View view) {
//调用中间人的方法,达到间接调用服务的业务逻辑方法的目的
myBinder.methodInService();
}
6.绑定服务的应用场景
推荐的混合方式:
1.starService:让程序长期运行在后台;
2.bindService:为了调用服务中业务逻辑方法;
3.unbinderService:停止调用服务里面业务逻辑方法;
4.unbindService:停止服务对象;
服务的应用场景:
天气预报、股票软件;
需要长期运行在后台,同时需要与服务器端定时通讯数据。
7.利用服务注册广播接收者
操作频繁的广播事件,如果使用系统注册,每次接受广播消息的时候都去配置文件查找接收事件类型,这样耗费时间。
手机屏幕锁屏、解屏;
步骤:
1.写一个广播接收者:
public class TestBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if("android.intent.action.SCREEN_ON".equals(action)){
System.out.println("=============SCREEN_ON===========");
}
if("android.intent.action.SCREEN_OFF".equals(action)){
System.out.println("=============SCREEN_OFF===========");
}
}
}
2.写一个服务类,在oncreate方法中注册广播接收者:
public class TestService extends Service {
@Override
public void onCreate() {
super.onCreate();
//使用代码注册广播接收者
TestBroadcastReceiver receiver = new TestBroadcastReceiver();
//创建一个意图过滤器,并且指定广播接收者接收的事件类型
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
//注册广播接收者,并且使用意图过滤器开启它
this.registerReceiver(receiver, filter);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
3.在清单文件中配置接收者和服务:
<receiver android:name="com.qaa.serviceregistereceiver.TestBroadcastReceiver">
</receiver>
<service android:name="com.qaa.serviceregistereceiver.TestService"></service>
8.远程服务aidl的写法(重点)
aidl:Android Interface definition language 安卓接口定义语言;
对外共享的接口文件。
远程服务:同一个设备上其他工程里面实现服务程序;
本地服务:在自己的工程中实现的服务的程序;
在本地应用程序中调用远程服务:
1、准备一个远程的服务的步骤:
(1)写了接口类,暴露出来一个方法;
(2)在服务类里面让中间人实现接口,并且实现接口里面的方法,方法里面调用服务的业务逻辑方法;
(3)把接口类改aidl类型文件:对外提供一个共享的接口文件;
(4)在服务类中让中间人继承Stub这个类。
代码:
1)写了接口类,暴露出来一个方法;
public interface IService {
public void callMethodInService();
}
(2)在服务类里面让中间人实现接口,并且实现接口里面的方法,方法里面调用服务的业务逻辑方法;
private class MyBinder extends Binder implement IService{
@Override
public void callMethodInService() {
//调用服务的业务逻辑方法
methodInService();
}
(3)把接口类改aidl类型文件:对外提供一个共享的接口文件;
IService.aidl;
(4)在服务类中让中间人继承Stub这个类:
private class MyBinder extends Stub{
@Override
public void callMethodInService() {
//调用服务的业务逻辑方法
methodInService();
}
}
3.创建一个本地应用程序,调用远程服务的接口的步骤:
(1)把远程服务中的接口文件拷贝到本地应用的工程,接口文件必须存放在与远程服务相同的包名中:
com.qaa.remoteservice:IService.aidl;
(2)创建一个隐式意图,开启远程的服务:
// 绑定服务
Intent intent = new Intent();
intent.setAction("com.qaa.remoteservice.REMOTESERVICE");
bindService(intent, new MyConn(), BIND_AUTO_CREATE);
3)绑定服务成功后,得到接口类型的中间人对象;
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//把服务中的中间人转换成一个接口类型的对象
myBinder = Stub.asInterface(service);
}
}
(4)调用接口类型中间人的方法;
public void call(View view) {
try {
//调用远程服务中业务逻辑方法
myBinder.callMethodInService();
}
catch (RemoteException e) {
e.printStackTrace();
}
}
9.补间动画
补间动画:图片平移、缩放、旋转、透明度效果等变化的过程。
工程代码:
布局文件:
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="平移"
android:onClick="trans" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="缩放"
android:onClick="scale"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="旋转"
android:onClick="rotate" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="透明"
android:onClick="alpha"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="组合"
android:onClick="set"
/>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv"
android:src="@drawable/dsx"
/>
</LinearLayout>
代码:
MainActivity.java:
package com.qaa.tween;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
public void trans(View view) {
// 创建平移的动画对象
TranslateAnimation ta = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_SELF, 0,TranslateAnimation.RELATIVE_TO_PARENT, 1.0f,TranslateAnimation.RELATIVE_TO_SELF,0, TranslateAnimation.RELATIVE_TO_PARENT, 1.0f);
// 设置动画播放的时间
ta.setDuration(3000);
// 设置动画重复播放的次数
ta.setRepeatCount(2);
// 设置动画重复播放的模式
ta.setRepeatMode(TranslateAnimation.REVERSE);
// 开始播放动画
iv.startAnimation(ta);
}
public void scale(View view) {
// 创建缩放的动画对象
ScaleAnimation sa = new ScaleAnimation(0, 2.0f, 0, 2.0f, ScaleAnimation.RELATIVE_TO_PARENT, 0.5f, ScaleAnimation.RELATIVE_TO_PARENT, 0.5f);
// 设置动画播放的时间
sa.setDuration(3000);
// 设置动画重复播放的次数
sa.setRepeatCount(2);
// 设置动画重复播放的模式 sa.setRepeatMode(ScaleAnimation.REVERSE);
// 开始播放动画
iv.startAnimation(sa);
}
public void rotate(View view) {
// 创建旋转的动画对象
RotateAnimation ta = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放的时间
ta.setDuration(3000);
// 设置动画重复播放的次数
ta.setRepeatCount(2);
// 设置动画重复播放的模式
ta.setRepeatMode(RotateAnimation.REVERSE);
// 开始播放动画
iv.startAnimation(ta);
}
public void alpha(View view) {
// 创建透明度的动画对象
// fromAlpha 初始透明度 0:完全透明 1.0f完全不透明
AlphaAnimation aa = new AlphaAnimation(0, 1.0f);
// 设置动画播放的时间
aa.setDuration(3000);
// 设置动画重复播放的次数
aa.setRepeatCount(2);
// 设置动画重复播放的模式
aa.setRepeatMode(RotateAnimation.REVERSE);
// 开始播放动画
iv.startAnimation(aa); }
public void set(View view) {
// shareInterpolator 动画插桶 为true表示按照动画的顺序一个一个的播放动画
AnimationSet set = new AnimationSet(false);
AlphaAnimation aa = new AlphaAnimation(0, 1.0f);
// 设置动画播放的时间
aa.setDuration(3000);
// 设置动画重复播放的次数
aa.setRepeatCount(2);
// 设置动画重复播放的模式
aa.setRepeatMode(RotateAnimation.REVERSE);
set.addAnimation(aa);
RotateAnimation ra = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放的时间
ra.setDuration(3000);
// 设置动画重复播放的次数
ra.setRepeatCount(2);
// 设置动画重复播放的模式
ra.setRepeatMode(RotateAnimation.REVERSE);
set.addAnimation(ra);
ScaleAnimation sa = new ScaleAnimation(0, 2.0f, 0, 2.0f, ScaleAnimation.RELATIVE_TO_PARENT, 0.5f, ScaleAnimation.RELATIVE_TO_PARENT, 0.5f);
// 设置动画播放的时间
sa.setDuration(3000);
// 设置动画重复播放的次数
sa.setRepeatCount(2);
// 设置动画重复播放的模式
sa.setRepeatMode(ScaleAnimation.REVERSE);
set.addAnimation(sa);
TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 200);
// 设置动画播放的时间
ta.setDuration(3000);
// 设置动画重复播放的次数
ta.setRepeatCount(2);
// 设置动画重复播放的模式
ta.setRepeatMode(TranslateAnimation.REVERSE);
set.addAnimation(ta);
// 播放动画集合
iv.startAnimation(set);
}
}