Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Error when closing admob interstital ads in Unity5

Discussion in 'Android' started by yyhuang, Oct 6, 2015.

  1. yyhuang

    yyhuang

    Joined:
    Nov 3, 2014
    Posts:
    3
    Recently I upgraded my project from Unity4.6 to Unity5.2.0f3.

    I have registered InterstitialAd.AdClosed Event to control the sound of game, and after upgrading I had error messages like the following when closing interstitial ads.

    ArgumentException: set_mute can only be called from the main thread

    The following code is simplified version of my code. It works correctly in Unity4.6.

    Code (CSharp):
    1. InterstitialAd page = new InterstitialAd(androidPageId);
    2. page.AdClosing += HandlePageClosing;
    3.  
    4. void HandlePageClosing(object sender, EventArgs args) {
    5.     // type of musicAudio is AudioSource
    6.     musicAudio.mute = false;
    7. }
    8.  
    I have found similar issues in iOS in this thread, not sure if they are related.

    Any help is appreicated!
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    Unity runs all scripting code from a single thread - the "scripting thread".

    When using native plugins, the native code may trigger a callback to Unity on some other thread (which is not the scripting thread). Maybe this is the case here (the AdClosing event gets raised on another thread).

    On Android, i think this is pretty common, as interstitials (that may be activities) must execute stuff on the application's main thread (only this thread can do UI related stuff), but this is not the same as Unity's scripting thread.

    This does not explain why it used to work before though :) maybe Unity became more strict as to which of its APIs can be invoked from a non-scripting thread ?

    The general solution for this is to not "touch" any Unity APIs from that thread. Instead, have a "task executer" object that is always alive (singleton), and that can accept tasks that should be executed.

    This object (in its Update method) will query for pending tasks and execute them one by one (on the scripting thread).

    Let me know if you require concrete code examples for that :)
     
  3. yyhuang

    yyhuang

    Joined:
    Nov 3, 2014
    Posts:
    3
    Yea I would like to know if this behaviour is intended or a bug. So I could decide to just wait for the fix or implement the task executer ;)

    Thanks for the detail of threads!