(每次学习一点xamarin就做个学习笔记和视频来加深记忆巩固知识)
如有不正确的地方,请帮我指正。
Service简介
服务就是没有任何界面,不需要和用户直接打交道且需要长时间在后台运行的程序。例如手机中的音乐播放服务、天气更新服务和下载服务等。
服务运行在主线程中的,为了不让主线程阻塞,所以要在服务内部创建子线程去处理任务。
Service分类
(按调用地点)
调用地点 | 说明 | 备注 |
---|---|---|
Local Service(本地服务) | Service对象与它的启动者在一个进程中,是进程内的通信。 | Service所在进程被结束后服务也就结束了。 |
Remote Service(远程服务) | Service对象与它的启动者不在一个进程中,是进程间的通信。可用AIDL来跨进程通信。 | 启动为独立进程,所以调用它的另一进程结束了,它也不会结束。 |
(按运行方式)
运行方式 | 说明 | 例子 |
---|---|---|
后台服务__ | 默认是后台服务,但优先级低,当系统内存不足时,可能会被回收掉。 | 天气更新服务 |
前台服务 | 它可防止被回收。它会有一个正在运行的图标在状态栏。 | 下载服务,音乐播放服务 |
服务的生命周期
先来看一张官方的图
从上图可看出有两种调用Service的方式。
第一种方式,在Activity中通过Context的StartService()方法来启动服务,然后onCreate()和onStartCommand()方法被执行,服务就处于运行中。Activity只是启动了下Service,并没有其它联系了。
第二种方式,通过Context的bindService()方法来启动服务,则可以把Activity和Service紧密联系起来,我们就可以在Activity中去控制Service按自己的要求去做处理了。例如我们要控制音乐的暂停,切歌等就需要Activity控制服务去处理。而第一种方式则不行。
服务的使用
查看Service类,它是一个抽象类,继续自Context上下文类,有如下几个主要方法:
public abstract class Service : ContextWrapper //而ContextWrapper 又是继承自Context
{
public virtual void OnCreate();
public virtual StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId);
public abstract IBinder OnBind(Intent intent);
public virtual void OnDestroy();
public void StartForeground(int id, Notification notification);
public void StopSelf();
}
对于上图中第一种使用方式,只需新建一个类继承自Service类,并重写OnCreate()、OnStartCommand和OnDestory三个方法即可。贴上部分代码如下:
[Service(Enabled =true,Exported =true)]
/*
上面的代码会在AndroidManifest.xml文件的application节点内生成如下代码
<service>
android:name=".MyService"
android:enabled="true"
android:exported="true"
</service>
*/
public class MyService : Service
{
public MyService()
{
}
public override void OnCreate()
{
base.OnCreate();
Log.Debug("MyService", "创建服务");
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
Log.Debug("MyService", "启动服务");
return base.OnStartCommand(intent, flags, startId);
}
public override void OnDestroy()
{
base.OnDestroy();
Log.Debug("MyService", "销毁服务");
}
public override IBinder OnBind(Intent intent)
{
return null;
}
}
对于上图中的第二种使用方式,则要用到如下类和接口:
类或接口 | 说明 |
---|---|
Service抽象类 | 长时间在后台运行任务。 |
Binder类 | 它用于进程间通信。在这里面写自己要处理的具体任务 |
IServiceConnection接口 | 用来监听Service的连接状态 |
查看Binder类,它实现了IBinder接口
public class Binder : Java.Lang.Object, IBinder
使用Binder类,举个例子:
public class MyDownloadBinder : Binder
{
public void BeginDownload()
{
Log.Debug("DownloadBinder", "开始下载");
}
public int GetProgress()
{
Log.Debug("DownloadBinder", "取得下载进度");
return 0;
}
}
查看IServiceConnection接口,它有定义了两个方法
namespace Android.Content
{
public interface IServiceConnection : IJavaObject, IDisposable
{
void OnServiceConnected(ComponentName name, IBinder service);//服务的连接建立后被调用
void OnServiceDisconnected(ComponentName name); //服务的连接断开后被调用,暂时用不到,不用管它
}
}
举个例子如下:
public class MyServiceConnection : Java.Lang.Object, IServiceConnection
{
private MyDownloadBinder _downloadBinder;
public MyServiceConnection(MyDownloadBinder binder)
{
_downloadBinder = binder;
}
//服务的连接建立后开始执行自己想要的任务
public void OnServiceConnected(ComponentName name, IBinder service)
{
_downloadBinder = (MyDownloadBinder)service;
_downloadBinder.BeginDownload();
_downloadBinder.GetProgress();
}
public void OnServiceDisconnected(ComponentName name)
{
}
}
还得修改MyService类,主要修改地方如下:
public class MyService : Service
{
private MyDownloadBinder _binder = new MyDownloadBinder();
//………………………………………省略其它代码
public override IBinder OnBind(Intent intent)
{
return _binder;
}
//………………………………………省略其它代码
}
在MainActivity中去启动服务
public class MainActivity : AppCompatActivity, IOnClickListener
{
private MyDownloadBinder _downloadBinder;
private MyServiceConnection _myServiceConnection;
//………………………………………省略其它代码
private void StartService()//启动本地服务(第一种方式即Context.StartService())
{
Intent intent = new Intent(this, typeof(MyService));
this.StartService(intent);
}
private void StopService()//停止本地服务
{
Intent intent = new Intent(this, typeof(MyService));
this.StopService(intent);
}
private void BindService()//绑定本地服务(第二种方式即Context.BindService())
{
Intent intent = new Intent(this, typeof(MyService));
if (_myServiceConnection == null)
{
_myServiceConnection = new MyServiceConnection(_downloadBinder);
this.BindService(intent, _myServiceConnection, Bind.AutoCreate);
}
}
private void UnBindService()//取消绑定本地服务
{
if (_myServiceConnection != null)
{
this.UnbindService(_myServiceConnection);
}
}
}
同时使用Context.StartService()和Context.BindService()
有时候需要使用Activity来控制Service并且Activity在Finishi后服务不被Destory,那么就得同时调用StartServie()和BindService()。
代码和视频在上传的CSDN资源中http://download.csdn.net/download/junshangshui/10121799