广播与服务(2)

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);     

}    

}

原文地址:https://www.cnblogs.com/kingqinwang/p/5129333.html