Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 526
Multimatt Avatar asked Jul 04 '14 10:07

Multimatt


1 Answers

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];
        }
    }];
}
like image 178
benka Avatar answered Oct 04 '22 12:10

benka