并行执行的Service,以媒体转码成新格式为例
大家众所周知,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,以媒体转码成新格式为例的更多相关文章
- 视频转码成mp4格式,添加关键帧,添加元数据,把元数据放在第一帧,可拖动
		
作者测试是在windows下使用,所以下载的页面地址是: http://ffmpeg.zeranoe.com/builds/点击页面上的Download FFmpeg git-738ebb4 64-b ...
 - 微信小程序silk格式转码成mp3格式
		
最近小程序项目需要录制语音并上传到服务器,经过查资料了解 目前微信小程序录音的文件后缀名是silk,因此需要转换. 经过查资料了解,参考一下的地址 https://github.com/kn007/s ...
 - DotNet 使用阿里云媒体转码服务
		
公司项目中一部分文件放到了阿里云 OSS 上,其中有些音频文件是 amr 类型的,在后期使用的时候比较麻烦,所以需要转换成 mp3 的文件,方便以后使用.本来想使用 ffmpeg 处理,但由于文件都存 ...
 - 七牛用户如何将视频转码成普清高清来适应不同的手机端或者web端
		
Qiniu 七牛问题解答 非常多人会用到七牛视频转码问题,要将视频转码成适用于各种终端的视频,也有的用户对转码服务的码率,帧率,分辨率等理解不多.不知道该怎样设置这些參数.以下我给大家科普一下. 问题 ...
 - 转: jquery.qrcode.js生成二维码插件&转成图片格式
		
原文地址: https://blog.csdn.net/u011127019/article/details/51226104 1.qrcode其实是通过使用jQuery实现图形渲染,画图,支持can ...
 - jmeter接口测试--响应结果Unicode转码成中文
		
jmeter接口测试-响应结果Unicode转码成中文 一般情况下,接口返回数据都会经过加密,所以有时相应结果会显示为Unicode,因此,需添加BeanShell PostProcessor,加入代 ...
 - Emscripten实现把C/C++文件转成wasm,wast(wasm的可读形式),llvm字节码(bc格式),ll格式(llvm字节码的可读形式)并执行wasm
		
<一>˙转换 Emscripten实现把C/C++文件转成wasm,wast(wasm的可读形式),llvm字节码(bc格式),ll格式(llvm字节码的可读形式)的步骤: 最新版本的Em ...
 - MP4文件批量转码成MP3
		
需求背景:最近为了学python爬虫,在论坛里找了不少视频教程,非常棒.但有时看视频不方便,就想着能否把视频批量转码成音频,这样在乘坐地铁公交的时候也能学习了. 解决路径:有了需求,我首先在论坛里搜了 ...
 - H264编码 封装成MP4格式 视频流 RTP封包
		
H264编码 封装成MP4格式 视频流 RTP封包 分类: 多媒体编程 2013-02-20 21:31 3067人阅读 ...
 
随机推荐
- Tiny6410声卡驱动——录音与回放
			
在Linux下,音频设备程序的实现与文件系统的操作密切相关.Linux将各种设备以文件的形式给出统一的接口,这样的设计使得对设备的编程与对文件的操作基本相同,对Linux内核的系统调用也基本一致,从而 ...
 - 安装Loopback网卡/回环网卡
			
$CurrentPath = $MyInvocation.MyCommand.Path.substring(0,$MyInvocation.MyCommand.Path.LastIndexOf('\' ...
 - applicationContext.xml存放的位置
			
web.xml中classpath:和classpath*: 有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件 ...
 - C++ 析构方法
			
1.什么是析构方法? 析构方法与构造方法互补. 2.为什么设计析构方法? 构造方法创建一个对象,对象内部往往还会申请一些资源.设计析构方法的目的是 释放资源,同时销毁自身. 3.析构方法可以认为分为两 ...
 - Android播播放完SD卡指定文件夹音乐之后,自动播放下一首
			
最近做一个项目,需要连续播放音乐,播放完一首歌之后,自动播放完下一首歌.不要重复播放. 代码如下: package com.example.asyncplayer_ex; import java.io ...
 - Android开发学习之 定制界面风格
			
统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...
 - Java中for循环以及循环中标签
			
1.第一种,通过迭代的方式 File[] listFiles = file.listFiles(); for (Iterator iterator = files.iterator(); iterat ...
 - StarlingMVC简介,原理解说及示例源码
			
StarlingMVC简介 StarlingMVC是一个为使用Starling来开发游戏的MVC框架.这个框架的特性方面,很像Swiz和RobotLegs,原理亦像Mate.其特性列表如下: 依赖注入 ...
 - Playing with ptrace, Part II
			
Playing with ptrace, Part II Issue From Issue # December Dec , By Pradeep Padala inSysAdmin In Part ...
 - JAMA:Java矩阵包
			
原文链接:JAMA:Java矩阵包 API文档链接:线性代数Java包 JAMA jama是一个非常好用的java的线性代数软件包.适用于日常编程可能碰到的各种矩阵运算问题,提供了一个优雅的简便的解决 ...