Phonegap "['Media'] Plugin should use a background thread."

background, cordova, media, multithreading, plugins

Solution

Personally I haven't yet used the `Media` plugin but to handle background threads you will need to check which call is causing the `warning`.

For example if this warning throws when you are creating a `media` object:

var my_media = new Media(src, onSuccess, onError);

Then you can check the plugins `.js` file (which is `Media.js`). Look for the function `Media` and look for the native call which is in this case:

exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);

From this you know that this is calling the `Media` class's `create` method. So go and open `Media.m` (or `CDVSound.m` in this exact case) and look for the `create` method (you should find it in `cordova/plugins/org.apache.cordova.media/src/ios`), end encapsulate the whole method with:

[self.commandDelegate runInBackground:^{
    // the create method goes here
}]; 

This will create a background thread for "native" Media creation. It should look like this:

- (void)create:(CDVInvokedUrlCommand*)command
{
    [self.commandDelegate runInBackground:^{
        NSString* mediaId = [command.arguments objectAtIndex:0];
        NSString* resourcePath = [command.arguments objectAtIndex:1];

        CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:NO forRecording:NO];

        if (audioFile == nil) {
            NSString* errorMessage = [NSString stringWithFormat:@"Failed to initialize Media file with path %@", resourcePath];
            NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMessage]];
            [self.commandDelegate evalJs:jsString];
        } else {
            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
        }
    }];
}

Problem

I am using Phonegap 3 and the Media plugin. I keep getting these errors when testing my app on iOS: ``` THREAD WARNING: ['Media'] took '205.391846' ms. Plugin should use a background thread. ``` I have seen this from the phonegap documentation (http://docs.phonegap.com/en/edge/guide_platforms_ios_plugin.md.html): ``` - (void)myPluginMethod:(CDVInvokedUrlCommand*)command { // Check command.arguments here. [self.commandDelegate runInBackground:^{ NSString* payload = nil; // Some blocking logic... CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload]; // The sendPluginResult method is thread-safe. [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }]; } ``` Does this go into my app as it is, or do I need to edit it for each plugin? Where do I put it? I've seen a few posts online about this, but none with a clear answer of how to use the above code.

Original source