展会信息港展会大全

Android 从类Service派生service
来源:互联网   发布日期:2016-01-13 22:13:43   浏览:2524次  

导读:从类Service派生如你在上节所见,使用类IntentService使得你实现一个"开始的"service非常容易.然而,如果你需要你的service以多线程方式执行(而不是使用工作队列),那么你需要从类Service派生来处理每个intent......

从类Service派生

如你在上节所见,使用类IntentService使得你实现一个"开始的"service非常容易.然而,如果你需要你的service以多线程方式执行(而不是使用工作队列),那么你需要从类Service派生来处理每个intent.

相比之下,下面的例子从类Service派生并实现了与上面使用IntentService例子完全相同的工作.也就是在一个线程中序列化的处理每个"开始"请求.

<span style="font-size:18px;">public class HelloService extends Service {

private Looper mServiceLooper;

private ServiceHandler mServiceHandler;

// 处理从线程收到的消息们

private final class ServiceHandler extends Handler {

public ServiceHandler(Looper looper) {

super(looper);

}

@Override

public void handleMessage(Message msg) {

// 通常我们在这里做一些工作比如下载一个文件

// 在我们的例子中,仅仅是睡5秒钟.

long endTime = System.currentTimeMillis() + 5*1000;

while (System.currentTimeMillis() < endTime) {

synchronized (this) {

try {

wait(endTime - System.currentTimeMillis());

} catch (Exception e) {

}

}

}

// 使用startId停止服务,从而使我们不会在处理

// 另一个工作的中间停止service

stopSelf(msg.arg1);

}

}

@Override

public void onCreate() {

// 启动运行service的线程.注意我创建了一个

// 分离的线程,因为service通常都是在进程的

// 主线程中运行,但我们不想让主线程阻塞.我们还把新线程

// 搞成后台级的优先级,从而减少对UI线程(主线程的影响).

HandlerThread thread = new HandlerThread("ServiceStartArguments",

Process.THREAD_PRIORITY_BACKGROUND);

thread.start();

// Get the HandlerThread's Looper and use it for our Handler

mServiceLooper = thread.getLooper();

mServiceHandler = new ServiceHandler(mServiceLooper);

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

// 对于每个开始请求,发送一消息来开始一次工作,并且把

// start ID也传过去,所以当完成一个工作时,我们才知道要停止哪个请求.

Message msg = mServiceHandler.obtainMessage();

msg.arg1 = startId;

mServiceHandler.sendMessage(msg);

// 如果我们在这里返回后被被杀死了,重启之.

return START_STICKY;

}

@Override

public IBinder onBind(Intent intent) {

// We don't provide binding, so return null

return null;

}

@Override

public void onDestroy() {

Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();

}

}

</span>

如你所见,要做的工作比使用IntentService时多一些.

然而,因为你自己处理每次对onStartCommand()的调用,你可以同时执行多个请求.这个例子并没有那样做,但是如果那是你所需要的,那么你可以为每个请求创建一个新的线程并且立即运行它们(而不是等待上一个请求完成).

注意方法onStartCommand()必须返回一个整数.这个整数描述了在系统杀死它的事件中系统如何继续这个服务(如前面所述,IntentService的默认实现为你处理这些,当然你也能够去改写它).onStartCommand()也返回值必须是下面常量之一:

START_NOT_STICKY

如果系统在onStartCommand()返回后杀死了服务,不要重新创建这个service,除非还有挂起的intent需要被传送.这是避免在不必要时运行你的service和当你的应用可以简单重启任何未竟的工作时的最佳选择.

START_STICKY

如果系统在onStartCommand()返回后杀死了这个service,会重新创建这个service并且调用onStartCommand(),但是不再重新发送上次最后一个intent,而是使用一个nullintent调用onStartCommand(),除非有一些挂起的intent,在此情况下,这些挂起的intent被派送.这适合于媒体播放器(or或相似也的服务),它不执行命令,但是无限期的运行并等待一个工作.

START_REDELIVER_INTENT

如果系统在onStartCommand()返回后杀死了service,重新创建这个service并且使用上次最后一个intent调用onStartCommand().任何挂起的intent都顺序地被派送.这适合于活跃地执行一个工作并且应被立即恢复的服务,比如下载一个文件.

赞助本站

人工智能实验室

相关热词: Service 派生

AiLab云推荐
展开

热门栏目HotCates

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