Android中的Service学习

Service是android 系统中的一种组件,它跟Activity的级别差不多,但是他不能自己运行,只能后台运行,并且可以和其他组件进行交互。Service运行在自己的进程空间中,有着自己的运行过程。

Service的权限(Permissions)

在manifest 文件中声明的Service可以被全局访问(所有的应用程序都可以访问这个Service)。为了可以访问这个Service,其他的程序需要在他们的manifest文件中声明相应的<uses-permission> 来使用启动、停止或者绑定到这个Service。

另外,Service可以通过权限(通过在执行那个调用的实现之前调用checkCallingPermission(String))保护自己的IPC调用。

Service的进程生命周期(Process LIfecycle)
Android系统会尽量保持使用Service的进程尽可能长(Service被启动或者有客户端绑定到Service)。当系统内存变低,系统需要kill现存的进程时,Service的hosting进程的优先级将会在下列的可能中保持更高。


 

Service的启动有两种方式:context.startService()context.bindService()。

使用 context. startService() 启动Service是会会经历:
context.startService()  ->onCreate()- >onStart()->Service running
context.stopService() | ->onDestroy() ->Service stop  
 
如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 
 
stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。
 
所以调用startService的生命周期为:onCreate --> onStart(可多次调用) --> onDestroy
 
使用使用 context .bindService()启动Service会经历:
context .bindService()->onCreate()->onBind() ->Service running
onUnbind() -> onDestroy() ->Service stop
 
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作(一般返回Service对象本身)。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。       
所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

service可以在和多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。


如果采用bindService()来启动Service的话,则将返回一个IBind接口的实例,该接口对象实现了对进程间通信的功能,类似于JAVA中的SOAP所实现的功能。。


下面以一个音乐播放的实例来介绍Service的Bind方法

1,首先创建一个主Activity

 

public class ServiceMusic extends Activity implements View.OnClickListener{
    /** Called when the activity is first created. */


bindService bs;
Button btnstart,btnstop,btnclose,btnquit;
TextView tv;
    final String ACTION="service_music";

final ServiceConnection sc=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "onServiceConn", 6000).show();
bs=((bindService.MyBinder)service).getService();
}


@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "onServiceDiscon", 6000).show();
}
};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnstart=(Button)findViewById(R.id.button1);
        btnstop=(Button)findViewById(R.id.button2);
        btnquit=(Button)findViewById(R.id.button3);
        btnclose=(Button)findViewById(R.id.button4);
        tv=(TextView)findViewById(R.id.prop); 
        btnstart.setOnClickListener(this);
        btnstop.setOnClickListener(this);
        btnquit.setOnClickListener(this);
        btnclose.setOnClickListener(this);
        
    }


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.button1: //启动服务  使按钮可用/不可用
Intent intent=new Intent(getApplicationContext(),bindService.class);
bindService(intent,sc,Context.BIND_AUTO_CREATE);
btnstart.setEnabled(false);
tv.setText("开始播放");
break;
case R.id.button2: //发送广播进行 暂停/播放  动作
Intent act=new Intent(ACTION);
if(bs!=null && bs.on)
{
act.putExtra("action", true); //暂停播放
tv.setText("暂停播放");
}
else
{
act.putExtra("action", false); //开始播放
tv.setText("开始播放");
}
sendBroadcast(act);
break;
case R.id.button3: //关闭程序
this.finish();
break;
case R.id.button4: //关闭服务   使得启动按钮可用
this.unbindService(sc);//.stopService(new Intent(this,bindService.class));
btnstart.setEnabled(true);
break;
}
}    
}



public class bindService extends Service {


private MediaPlayer mp;

public boolean on=false;

public MyReceiver receiver=new MyReceiver();

class MyBinder extends Binder
{
bindService getService()
{
return bindService.this;
}
}

class MyReceiver extends BroadcastReceiver
{

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
boolean acti;
acti=intent.getExtras().getBoolean("action");
if(acti) //如果发送暂停的指令
{
pause();
}
else //如果发送 重新开始的指令
{
play();
}
}
}

//暂停播放
public void pause()
{
if(on && mp!=null) //如果在播放中
{
mp.stop();
on=false;
}
}

@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub

if(mp!=null)
{
mp.start();
on=true;
}
Toast.makeText(this,"Bind",3000).show();
return new MyBinder();
}


@Override
public void onCreate() {
// TODO Auto-generated method stub
IntentFilter filter=new IntentFilter("service_music");
registerReceiver(receiver,filter);
if(mp==null)
{
mp=new MediaPlayer();
try{
mp.setDataSource("/sdcard/alarm.mp3");
mp.prepare();
}catch(Exception e)
{
e.printStackTrace();
}
}
Toast.makeText(this,"Create",3000).show();
super.onCreate();
}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
if(mp!=null)
{
mp.stop();
mp.release();
}
unregisterReceiver(receiver);
this.stopSelf();

Toast.makeText(this,"Destory",3000).show();
// super.onDestroy();
}

@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(this,"onUnbind",3000).show();
return super.onUnbind(intent);
}

public void play()
{
if(!on && mp!=null)
{
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
on=true;
}
}
}

至此就可以通过Service实现在后台播放音乐的功能,

需要注意的是适用Context.startActivity()方法来实现启动Service时,会依次调用  ->onCreate()- >onStart()->Service running 

如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。

stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。


使用使用context.bindService()启动Service会经历:
context.bindService()->onCreate()->onBind()->Service running
onUnbind() -> onDestroy() ->Service stop 
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值