Search code examples
javaandroidadmob

How do I call a function on the Main Thread from a function in a JavascriptInterface that is triggered from my javascript in the html WebView?


I have the following in my JavascriptInterface. A javascript function on my webView html page calls the function triggerAdvert.

public class WebAppInterface {
    MainActivity m_Context; // This is set in construction

   WebAppInterface(MainActivity c) {
       m_Context = c;
   }

   ...

    @android.webkit.JavascriptInterface
    public void triggerAdvert() {
        MainActivity act = (MainActivity) m_Context;
        if(act != null) act.ShowAd();
    }
}

In my MainActivity I have the function ShowAd

public class MainActivity extends AppCompatActivity {
    ...
    // --- RewardedAd ---
    MyRewardedAd m_AdR = null;
    String rewardedID = "ca-app-pub-3940256099942544/5224354917"; // Test
    //String rewardedID = "?????????????????"; // Real for CMG
    private RewardedAd rewardedAd = null;
    private final String TAG = "MainActivity";
    long milliBetweenRewardedAd = 10 * 60 * 1000;
    long milliLastRewardedAd = 0;

    ...

    public void ShowAd(){
        long milliNow = System.currentTimeMillis();
        boolean showAd = (milliBetweenRewardedAd > 0 &&
                milliNow >= (milliBetweenRewardedAd + milliLastRewardedAd))
                ? true : false;

        if (showAd && rewardedAd != null) {
            Activity activityContext = MainActivity.this;
            rewardedAd.show(activityContext, new OnUserEarnedRewardListener() {
                @Override
                public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
                    // Handle the reward.
                    //Log.d(TAG, "The user earned the reward.");
                    int rewardAmount = rewardItem.getAmount();
                    String rewardType = rewardItem.getType();

                    milliLastRewardedAd = System.currentTimeMillis();
                }
            });
        } else {
            //Log.d(TAG, "The rewarded ad wasn't ready yet.");
        }
    }
}

The program complains I am not calling the rewardedAd.show on the main thread.

How do I overcome this?


Solution

  • You're getting this error because all Android UI operations must be performed on the main thread. To overcome this issue, you should post your action to the main thread using a Handler bound to the main Looper:

    public class WebAppInterface {
    
        private Handler handler = new Handler(Looper.getMainLooper()); // Create a handler
    
        @android.webkit.JavascriptInterface
        public void triggerAdvert() {
            handler.post(new Runnable() { // post this runnable to handler
                @Override
                public void run() {
                    MainActivity act = (MainActivity) m_Context;
                    if (act != null) act.ShowAd();
                }
            });
        }
    }