展会信息港展会大全

android控件service详细介绍
来源:互联网   发布日期:2016-01-13 22:21:57   浏览:1304次  

导读:1、什么是service Service,看名字就知道跟正常理解的服务差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需 要通过某一个Activity或者其他Context对象来调用......

1、什么是service

Service,看名字就知道跟正常理解的 服务 差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需 要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。

两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好 在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。

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

Service是在一段不定的时间运行在后台,不和用户交互应用组件。每个Service必须在manifest中 通过<service>来声明。可以通过contect.startservice和contect.bindserverice来启动。

Service和其他的应用组件一样,运行在进程的主线程中。这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现。

service的两种模式(startService()/bindService()不是完全分离的):

1)本地服务 Local Service 用于应用程序内部。

它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用 Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次 stopService()来停止服务。

用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。

2)远程服务 Remote Service 用于android系统内部的应用程序之间。

它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用 Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载 它。

可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

2、本地服务

2.1 startservice方式

Service的启动方式一:

启动:Context.startService(new Intent(context,xxx.class));

停止:Context.stopService() ;

我画了一个Service启动的流程图,相信大家一看就懂。Activity通过Intent启动Service,如果Service还没有运行,则 android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个 Service的onStart方法可能会重复调用多次。 调用stopService就会触发Service的onDestroy()方法。 图片点击放大~

我们先来介绍一下本地服务的例子。

2.1.1 界面

其中可以播放音乐、暂停、停止等。同时点击finish键可以关闭应用(但服务不关闭,音乐可以继续播放),点击exit推出 应用,同时关闭服务。

2.1.2 音乐播放

/**

* ClassName:MyMediaController

* Function: Mediaplayer 的一个控制类,控制播放器的播放 暂停 停止 等动作

* REASON

*

* @author Leon

* @version

* @since Ver 1.1

* @Date 2011-5-16

*/

public enum MyMediaController implements Serializable {

play {

@Override

public void execute() {

if (mediaPlayer != null && !mediaPlayer.isPlaying())

mediaPlayer.start();

// TODO Auto-generated method stub

}

},

pause {

@Override

public void execute() {

// TODO Auto-generated method stub

if (mediaPlayer != null && mediaPlayer.isPlaying()) {

mediaPlayer.pause();

}

}

},

stop {

@Override

public void execute() {

// TODO Auto-generated method stub

if (mediaPlayer != null) {

mediaPlayer.stop();

try {

// 在stop后如果要重新Start需要prepare一下

mediaPlayer.prepare();

// 从头播放

mediaPlayer.seekTo(0);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

};

public static MediaPlayer mediaPlayer;

public abstract void execute();

}

2.1.3 service

/**

* ClassName:MusicService

* Function: TODO ADD FUNCTION

* Reason:TODO ADD REASON

*

* @authorLeon

* @version

* @sinceVer 1.1

* @Date2011-5-15

*/

public class MusicService extends Service{

privateStringTAG = MusicService.class.getSimpleName();

privateMediaPlayer myMediaPlayer ;

publicstatic finalString INTENT_KEY= "action" ;

@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

return null;

}

@Override

public void onCreate() {

// TODO Auto-generated method stub

Log.v(TAG , TAG+ " onCreate()");

super.onCreate();

if(myMediaPlayer==null){

myMediaPlayer=MediaPlayer.create(this, R.raw.test) ;

myMediaPlayer.setLooping(false);

}

}

@Override

public void onStart(Intent intent, int startId) {

// TODO Auto-generated method stub

Log.v(TAG , TAG + " onStart()");

super.onStart(intent, startId);

if(intent!=null){

MyMediaController mediaControl =(MyMediaController)intent.getSerializableExtra(MusicService.INTENT_KEY);

mediaControl.mediaPlayer=myMediaPlayer;

mediaControl.execute();

}

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

Log.v(TAG , " onDestroy");

if(myMediaPlayer!=null){

myMediaPlayer.stop();

myMediaPlayer.release();

}

}

}

2.1.4 界面

public class ServiceTestServerActivity extends Activity implements OnClickListener{

/** Called when the activity is first created. */

private static final String TAG = ServiceTestServerActivity.class.getSimpleName();

private TextView m_TextView_text;

private Button btnPlay;

private Button btnPause;

private Button btnStop;

private Button btnFinish;

private Button btnExit;

Intent intent;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

m_TextView_text= (TextView)findViewById(R.id.text);

btnPlay= (Button)findViewById(R.id.play);

btnPause= (Button)findViewById(R.id.pause);

btnStop= (Button)findViewById(R.id.stop);

btnFinish= (Button)findViewById(R.id.finish);

btnExit= (Button)findViewById(R.id.exit);

btnPlay.setOnClickListener(this);

btnPause.setOnClickListener(this);

btnStop.setOnClickListener(this);

btnFinish.setOnClickListener(this);

btnExit.setOnClickListener(this);

intent=new Intent("xuxm.demo.service01.MusicService");

}

private void playAction(MyMediaController playType) {

Bundle bundle = new Bundle();

bundle.putSerializable(MusicService.INTENT_KEY, playType);

intent.putExtras(bundle);

ServiceTestServerActivity.this.startService(intent);

}

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

switch(v.getId())

{

case R.id.play:

playAction(MyMediaController.play);

m_TextView_text.setText(R.string.play);

Log.d(TAG, "play.......");

break;

case R.id.pause:

playAction(MyMediaController.pause);

m_TextView_text.setText(R.string.pause);

Log.d(TAG, "pause.......");

break;

case R.id.stop:

playAction(MyMediaController.stop);

m_TextView_text.setText(R.string.stop);

Log.d(TAG, "stop.......");

break;

case R.id.finish:

Log.d(TAG, "close.......");

this.finish();

break;

case R.id.exit:

Log.d(TAG, "exit.......");

stopService(intent);

this.finish();

break;

default:

}

}

}

程序还是蛮简单的,所以不分析了。

运行时可以发现第一次startService时,会调用onCreate和onStart,在没有stopService前,无论点击多少次 startService,都只会调用onStart。而stopService时调用onDestroy。再次点击stopService,会发现不会 进入service的生命周期的,即不会再调用onCreate,onStart和onDestroy。

而onBind在startService/stopService中没有调用。

2.1 bind service方式

第二种是通过绑定的方式来启动Service。先看流程图,点击放大。

在这里我们使用了this.bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);来启动Service,当Service创建了同时绑定了之后,会回调我们定义的ServiceConnection(),从而传回IBinder接 口,我们就能够调用Service中的方法了。这时候Activity就和Service实现了绑定,Activity退出了Service就相应的退出 了。

<service android:name=".MusicService02" >

<intent-filter >

<action android:name="xuxm.demo.service02.MusicService" />

</intent-filter>

</service>

主要代码如下:

MusicService02

public class MusicService02 extends Service{

privateStringTAG = MusicService02.class.getSimpleName();

privateMediaPlayer myMediaPlayer ;

publicstatic finalString INTENT_KEY= "action" ;

@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

Log.v(TAG, TAG+" onBind");

return mbinder;

}

LocalBinder mbinder=new LocalBinder();

public class LocalBinder extends Binder {

MusicService02 getService() {

return MusicService02.this;

}

}

@Override

public void onCreate() {

// TODO Auto-generated method stub

Log.v(TAG , TAG+ " onCreate()");

super.onCreate();

if(myMediaPlayer==null){

myMediaPlayer=MediaPlayer.create(this, R.raw.test) ;

myMediaPlayer.setLooping(false);

}

}

@Override

public void onStart(Intent intent, int startId) {

// TODO Auto-generated method stub

Log.v(TAG , TAG + " onStart()");

super.onStart(intent, startId);

}

@Override

public boolean onUnbind(Intent intent) {

// TODO Auto-generated method stub

Log.v(TAG , TAG +" onUnbind ,成功没有?" + super.onUnbind(intent));

return true;

//return false;

}

@Override

public void onRebind(Intent intent) {

// TODO Auto-generated method stub

Log.v(TAG , TAG +" onRebind()----------------------------------->");

super.onRebind(intent);

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

Log.v(TAG , " onDestroy");

if(myMediaPlayer!=null){

myMediaPlayer.stop();

myMediaPlayer.release();

}

}

public MediaPlayer getMyMediaPlayer() {

return myMediaPlayer;

}

public void setMyMediaPlayer(MediaPlayer myMediaPlayer) {

this.myMediaPlayer = myMediaPlayer;

}

}

ServiceTestServerActivity

public class ServiceTestServerActivity extends Activity implements OnClickListener{

/** Called when the activity is first created. */

private static final String TAG = ServiceTestServerActivity.class.getSimpleName();

private TextView m_TextView_text;

private Button btnPlay;

private Button btnPause;

private Button btnStop;

private Button btnUnbind;

private Button btnFinish;

private Button btnExit;

private MusicService02 bindMusicService;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

m_TextView_text= (TextView)findViewById(R.id.text);

btnPlay= (Button)findViewById(R.id.play);

btnPause= (Button)findViewById(R.id.pause);

btnStop= (Button)findViewById(R.id.stop);

btnFinish= (Button)findViewById(R.id.finish);

btnExit= (Button)findViewById(R.id.exit);

btnPlay.setOnClickListener(this);

btnPause.setOnClickListener(this);

btnStop.setOnClickListener(this);

btnFinish.setOnClickListener(this);

btnExit.setOnClickListener(this);

connection();

}

private void connection() {

Log.v(TAG , TAG+"connection");

Intent intent = new Intent("xuxm.demo.service02.MusicService");

//this.startService(intent);

this.bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);

}

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

switch(v.getId())

{

case R.id.play:

MyMediaController.play.execute();

m_TextView_text.setText(R.string.play);

Log.d(TAG, "play.......");

break;

case R.id.pause:

MyMediaController.pause.execute();

m_TextView_text.setText(R.string.pause);

Log.d(TAG, "pause.......");

break;

case R.id.stop:

MyMediaController.stop.execute();

m_TextView_text.setText(R.string.stop);

Log.d(TAG, "stop.......");

break;

case R.id.finish:

Log.d(TAG, "close.......");

this.finish();

break;

case R.id.exit:

Log.d(TAG, "exit.......");

this.finish();

this.stopService(new Intent("xuxm.demo.service02.MusicService"));

break;

default:

}

}

//调用bindService后 Service调用onBind()后 回调此函数

private ServiceConnection myServiceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder binder) {

// This is called when the connection with the service has been

// established, giving us the service object we can use to

// interact with the service.Because we have bound to a explicit

// service that we know is running in our own process, we can

// cast its IBinder to a concrete class and directly access it.

Log.v(TAG , TAG+ "onServiceConnected");

// TODO Auto-generated method stub

bindMusicService = ((LocalBinder)binder).getService();

//给Controller设置Service初始化的MediaPlayer

MyMediaController.mediaPlayer=bindMusicService.getMyMediaPlayer();

}

@Override

public void onServiceDisconnected(ComponentName name) {

// This is called when the connection with the service has been

// unexpectedly disconnected -- that is, its process crashed.

// Because it is running in our same process, we should never

// see this happen.

// TODO Auto-generated method stub

bindMusicService=null;

Log.v(TAG, "..............onServiceDisconnected");

}

};

//当Activity finish时必须解绑 不然会出现溢出

@Override

public void finish() {

// TODO Auto-generated method stub

super.finish();

this.unbindService(myServiceConnection);

}

}

运行时,发现调用次序是这样的:

bindService:

1.MusicService02: onCreate

2.MusicService02: onBind

3.Activity: onServiceConnected

unbindService: 只是调用onDestroy

可见,onStart是不会被调用的,而onServiceDisconnected没有调用的原因在上面代码的注释有说明。

此时,activity停止时,service也停止了。

2.2 bind service的一些问题

前面的分析中可以看到Activity和Service,context.startService对应着Service中的onStart()方 法,context.onBindService对应的是Service中的onBind()方法。当我们继想绑定一个Service又想在 Activity停止时,Service不会停止,我们可以先StartService,然后再BindService()。这时候的流程图如下所示:

此时需要注意一个问题,当Activity退出的时候,Sercvice并不会停止,此时我们可以再进入Activity重新绑定,当这时候 Service就会调用onRebind()方法,但是调用onRebind()方法的前提是先前的onUnbind()方法执行成功,但是使用 super.onUnbind(intent)是执行不成功的,这时候我们要手动的使其返回true,再次绑定时Rebind()就会执行。否则,如果退 出时不显示的指定onUnbind()为成功的话(为false),那么重新启动此Activity来绑定服务时,Service的onBind()方法 和onReBind都不会执行,但是ServiceConnection方法确一定会回调了。这说明在Service中的onBind()方法不同于 onStart()方法不能被重复调用。

赞助本站

人工智能实验室

相关热词: service

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港