大家众所周知,IntentService内置的handler只有一个线程,而AsyncTask又只适合时间至多几秒的操作,所以我们关注使用ExecutorService建立并行执行。为了确保Service一直保持活跃状态,需要调用Service.startForeground()方法。由于Service.startForeground()和Service.stopForeground()并不会叠加,所以还需要维护一个内部计数器,用来记录活跃的任务。一旦计数器为0则调用Service.stopForeground();

在这个例子中,主要介绍怎么利用Service执行并行的任务,并不是主要讲解多媒体格式文件转码的操作,所以转码操作都省略,主要实现并行执行。

public class MediaTranscoder extends Service {
private static final int NOTIFICATION_ID = 1001;//定义通知的标识ID
public static final String ACTION_TRANSCODE_MEDIA = "com.liyaunjinglyj.services.TRANSCODE_MEDIA";
public static final String EXTRA_OUTPUT_TYPE = "outputType";//转码的类型
private ExecutorService mExecutorService;//定义线程池
private int mRunningJobs = 0;//任务计数器
private final Object mLock = new Object();//锁
private boolean mIsForeground = false;//标志是否需要结束Service

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
this.mExecutorService = Executors.newCachedThreadPool();//缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务,因此在一些面向连接的daemon型SERVER中用得不多。能reuse的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移出池。
注意,放入CachedThreadPool的线程不必担心其结束,超过TIMEOUT不活动,其会自动被终止。
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (ACTION_TRANSCODE_MEDIA.equals(action)) {
String outputType = intent.getStringExtra(EXTRA_OUTPUT_TYPE);

//启动新的作业增加计数器
synchronized (mLock) {
TranscodeRunnable transcodeRunnable = new TranscodeRunnable(
intent.getData(), outputType);
mExecutorService.execute(transcodeRunnable);//执行当前线程
mRunningJobs++;//线程计数器加1
startForegroundIfNeeded();//创建通知,并保持活跃
}
}
return START_NOT_STICKY;//系统回收资源关闭了当前的Service并不会重新启动.适合执行一次性操作。
}

@Override
public void onDestroy() {
super.onDestroy();
this.mExecutorService.shutdownNow();//shutdownNow() 方法阻止等待任务启动并试图停止当前正在执行的任务
}

private class TranscodeRunnable implements Runnable {
private Uri mInData;
private String mOutputType;

private TranscodeRunnable(Uri inData, String outputType) {
this.mInData = inData;
this.mOutputType = outputType;
}

@Override
public void run() {

//在这里执行转码操作

//转码完成后,计数器加1

synchronized (mLock) {
mRunningJobs--;
stopForegroundIfAllDone();
}
}

}

private void stopForegroundIfAllDone() {
if (mRunningJobs == 0 && mIsForeground) {
stopForeground(true);
this.mIsForeground = false;
}
}

private void startForegroundIfNeeded() {
if (!mIsForeground) {
Notification notification = buildNotFication();
startForeground(NOTIFICATION_ID, notification);
this.mIsForeground = true;
}
}

private Notification buildNotFication() {
Notification notification = null;

//在这里构建通知
return notification;
}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

并行执行的Service,以媒体转码成新格式为例的更多相关文章

  1. 视频转码成mp4格式,添加关键帧,添加元数据,把元数据放在第一帧,可拖动

    作者测试是在windows下使用,所以下载的页面地址是: http://ffmpeg.zeranoe.com/builds/点击页面上的Download FFmpeg git-738ebb4 64-b ...

  2. 微信小程序silk格式转码成mp3格式

    最近小程序项目需要录制语音并上传到服务器,经过查资料了解 目前微信小程序录音的文件后缀名是silk,因此需要转换. 经过查资料了解,参考一下的地址 https://github.com/kn007/s ...

  3. DotNet 使用阿里云媒体转码服务

    公司项目中一部分文件放到了阿里云 OSS 上,其中有些音频文件是 amr 类型的,在后期使用的时候比较麻烦,所以需要转换成 mp3 的文件,方便以后使用.本来想使用 ffmpeg 处理,但由于文件都存 ...

  4. 七牛用户如何将视频转码成普清高清来适应不同的手机端或者web端

    Qiniu 七牛问题解答 非常多人会用到七牛视频转码问题,要将视频转码成适用于各种终端的视频,也有的用户对转码服务的码率,帧率,分辨率等理解不多.不知道该怎样设置这些參数.以下我给大家科普一下. 问题 ...

  5. 转: jquery.qrcode.js生成二维码插件&转成图片格式

    原文地址: https://blog.csdn.net/u011127019/article/details/51226104 1.qrcode其实是通过使用jQuery实现图形渲染,画图,支持can ...

  6. jmeter接口测试--响应结果Unicode转码成中文

    jmeter接口测试-响应结果Unicode转码成中文 一般情况下,接口返回数据都会经过加密,所以有时相应结果会显示为Unicode,因此,需添加BeanShell PostProcessor,加入代 ...

  7. Emscripten实现把C/C++文件转成wasm,wast(wasm的可读形式),llvm字节码(bc格式),ll格式(llvm字节码的可读形式)并执行wasm

    <一>˙转换 Emscripten实现把C/C++文件转成wasm,wast(wasm的可读形式),llvm字节码(bc格式),ll格式(llvm字节码的可读形式)的步骤: 最新版本的Em ...

  8. MP4文件批量转码成MP3

    需求背景:最近为了学python爬虫,在论坛里找了不少视频教程,非常棒.但有时看视频不方便,就想着能否把视频批量转码成音频,这样在乘坐地铁公交的时候也能学习了. 解决路径:有了需求,我首先在论坛里搜了 ...

  9. H264编码 封装成MP4格式 视频流 RTP封包

    H264编码 封装成MP4格式 视频流 RTP封包         分类:             多媒体编程              2013-02-20 21:31     3067人阅读    ...

随机推荐

  1. 创建类模式(三):创建者(Builder)

    定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.这使得构件算法和组装方式可以独立应对变化:复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式 ...

  2. FluentData微型ORM

    最近在帮朋友做一个简单管理系统,因为笔者够懒,但是使用过的NHibernate用来做这中项目又太不实际了,索性百度了微型ORM,FluentData是第一个跳入我眼睛的词.简单的了解下FluentDa ...

  3. Codeforces Round #219 (Div. 1)(完全)

    戳我看题目 A:给你n个数,要求尽可能多的找出匹配,如果两个数匹配,则ai*2 <= aj 排序,从中间切断,分成相等的两半后,对于较大的那一半,从大到小遍历,对于每个数在左边那组找到最大的满足 ...

  4. Spring3.0 入门进阶(三):基于XML方式的AOP使用

    AOP是一个比较通用的概念,主要关注的内容用一句话来说就是"如何使用一个对象代理另外一个对象",不同的框架会有不同的实现,Aspectj 是在编译期就绑定了代理对象与被代理对象的关 ...

  5. MSSQL索引优化

    转自:http://blog.itpub.net/16436858/viewspace-589275/ http://www.cnblogs.com/jams742003/archive/2011/1 ...

  6. NHibernate - ICriteria 查询

    http://blog.knowsky.com/213234.htm http://blog.chinaunix.net/uid-20463341-id-1673509.html http://www ...

  7. setbuf和freopen

    看memcached代码的时候学习了一个api,setbuf,可以设置文件流的缓冲区.        #include <stdio.h> void setbuf(FILE *stream ...

  8. AOV网络拓扑排序

    这个算法,主要是为输出一个无环图的拓扑序列 算法思想: 主要依赖一个栈,用来存放没有入度的节点,每次读取栈顶元素,并将栈顶元素的后继节点入度减一,如果再次出现入度为零的节点,就加入到栈中.参考< ...

  9. opennebula 编译日志

    [root@localhost opennebula-]# scons mysql=yes scons: Reading SConscript files ... Testing recipe: xm ...

  10. ecshop后台限制IP登录

    ecshop是开源系统,所以难免会有漏洞   黑客攻击网站,往往是通过漏洞获取后台管理员权限,然后再做一些破坏 如果我们在后台文件里限制指定的IP才能登录后台,就相对安全多了 下面给出大家解决方案: ...