As we all know, the Intentservice built-in handler has only one thread, and asynctask is only suitable for operations up to a few seconds, so we are concerned with using executorservice to establish parallel execution. To ensure that the service remains active, you need to call the Service.startforeground () method. Because Service.startforeground () and Service.stopforeground () do not overlap, an internal counter is maintained to record active tasks. Once the counter is 0, call Service.stopforeground ();
In this example, the main introduction of how to use the service to perform parallel tasks, not the main explanation of the multimedia format file transcoding operation, so transcoding operations are omitted, mainly to achieve parallel execution.
public class Mediatranscoder extends Service {
private static final int notification_id = 1001;//define the ID of the notification
public static final String Action_transcode_media = "Com.liyaunjinglyj.services.TRANSCODE_MEDIA";
public static final String Extra_output_type = "OutputType";//transcoding type
Private Executorservice Mexecutorservice;//define thread pool
private int mrunningjobs = 0;//Task counter
Private Final Object MLock = new Object ();//Lock
Private Boolean misforeground = false;//Flag whether to end service
@Override
Public IBinder Onbind (Intent Intent) {
return null;
}
@Override
public void OnCreate () {
Super.oncreate ();
This.mexecutorservice = Executors.newcachedthreadpool ();//cache pool, see if there are any previously established threads in the pool, and if so, reuse. If not, a new thread is added to the pool, and the cache pool is typically used to perform some short-lived asynchronous tasks, so it is not much used in some connection-oriented daemon servers. The thread that can reuse, must be timeout idle within the pool thread, the default timeout is 60s, more than this idle time, the thread instance will be terminated and removed from the pool. Note that the thread that is put into the cachedthreadpool does not have to worry about its end, exceeding timeout inactivity, which is automatically terminated.
}
@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);
//Start a new job increase counter
Synchronized (MLock) {
Transcoderunnable transcoderunnable = new Transcoderunnable (
Intent.getdata (), outputtype);
Mexecutorservice.execute (transcoderunnable);//execute current thread
mrunningjobs++;//Thread counter plus 1
Startforegroundifneeded ();//Create notifications and stay active
}
}
return start_not_sticky;//System recycle resource closed the current service does not restart. Suitable for one-time operation.
}
@Override
public void OnDestroy () {
Super.ondestroy ();
This.mExecutorService.shutdownNow ();the//shutdownnow () method prevents the wait task from starting and attempts to stop the currently executing task
}
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 () {
Perform the transcoding operation here
When transcoding is complete, the counter adds 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;
Build a notification here
return notification;
}
}
Service in parallel execution, with media transcoding as a new format example