[solved] JVM Exception occured: #008 Must be called on main ui, when calling a method from PythonSDLActivity.java

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
phoenix13032005
Newbie
Posts: 2
Joined: Sun Mar 03, 2024 3:02 pm
Contact:

[solved] JVM Exception occured: #008 Must be called on main ui, when calling a method from PythonSDLActivity.java

#1 Post by phoenix13032005 »

Summary :

First of all thanks to anyone who will even give time to read this long as hell post, I appreciate every bit of help :(

To give a brief summary of what I have done :
  • I made a textbutton which jumps to a label that calls a function to show a RewardedAd in-game on android.
  • In the function I autoclass the PythonSDLActivity class and call my self-defined methods, both non-static.
  • I build the Android apk, copy projects folder from rapt and edit dependencies and everything else necessary in android studio
  • I test both my functions in PythonSDLActivity.java by calling them from onCreate() and I can see my ad
  • But after I try to call it normally in game using above mentioned textbutton, I get errors


The Errors

Case 1 :
I call the loadRewardedAd() method from onCreate and the showRewardedAd method from script.rpy.
I get my logged statement from loadRewardedAd() that the ad was loaded. But the showRewardedAd() method says that the ad wasnt loaded

Case 2 :
I call both methods from script.rpy
I get a runtime error from renpy debugger as follows :
JavaException: JVM Exception occured: #008 Must be called on the main UI thread
which is believe is only for the loadRewardedAd() method because showRewardedAd() was running fine when called from script.rpy as mentioned in case 1



The Problem
I have tried a few ways of trying to get the code inside the methods to run exclusively on main ui thread by using runOnUiThread() but it doesnt even execute the code, let alone show errors. I am honestly at a loss of what to do at this point.

If anyone wants to read the code, I have provided it below for reference.



Reference Code Snippets


From script.rpy

The label

Code: Select all

label AdShowLab:  
    $ showAd()
    jump start1
The showAd() function

Code: Select all

init python:
    def showAd():
        if renpy.android:
            from jnius import autoclass
            PythonSDLActivity = autoclass("org.renpy.android.PythonSDLActivity")
            pythonsdlactivity = PythonSDLActivity()
            pythonsdlactivity.loadRewardedAd()
            pythonsdlactivity.showRewardedAd()
        else:
            PythonSDLActivity = None

From PythonSDLActivity.java

Note : rewardedAd is an object of the RewardedAd class, defined in PythonSDLActivity class as a public static variable.

The showRewardedAd() function

Code: Select all

public void loadRewardedAd()
    {
                AdRequest adRequest = new AdRequest.Builder().build();
                RewardedAd.load(PythonSDLActivity.this, "ca-app-pub-3940256099942544/5224354917",
                        adRequest, new RewardedAdLoadCallback() {
                            @Override
                            public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                                // Handle the error.
                                super.onAdFailedToLoad(loadAdError);
                                Log.d(TAG, loadAdError.toString());
                                rewardedAd = null;
                            }

                            @Override
                            public void onAdLoaded(@NonNull RewardedAd ad) {
                                super.onAdLoaded(ad);
                                rewardedAd = ad;
                                Log.d(TAG, "Ad was loaded."+rewardedAd);
                                rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
                                    @Override
                                    public void onAdClicked() {
                                        // Called when a click is recorded for an ad.
                                        Log.d(TAG, "Ad was clicked.");
                                    }

                                    @Override
                                    public void onAdDismissedFullScreenContent() {
                                        // Called when ad is dismissed.
                                        // Set the ad reference to null so you don't show the ad a second time.
                                        Log.d(TAG, "Ad dismissed fullscreen content.");
                                        rewardedAd = null;
                                    }

                                    @Override
                                    public void onAdFailedToShowFullScreenContent(AdError adError) {
                                        // Called when ad fails to show.
                                        Log.e(TAG, "Ad failed to show fullscreen content.");
                                        rewardedAd = null;
                                    }

                                    @Override
                                    public void onAdImpression() {
                                        // Called when an impression is recorded for an ad.
                                        Log.d(TAG, "Ad recorded an impression.");
                                    }

                                    @Override
                                    public void onAdShowedFullScreenContent() {
                                        // Called when ad is shown.
                                        Log.d(TAG, "Ad showed fullscreen content.");
                                    }
                                });
                            }
                        });

    }
The loadRewardedAd() function :

Code: Select all

public void showRewardedAd()
    {
        Log.d(TAG, "Ad type is "+rewardedAd);
        if (rewardedAd != null)
        {
            Activity activityContext = PythonSDLActivity.this;
            rewardedAd.show(activityContext, rewardItem -> {
                // Handle the reward.
                Log.d(TAG, "The user earned the reward.");
                int rewardAmount = rewardItem.getAmount();
                String rewardType = rewardItem.getType();
                Log.d(TAG, "showing ad "+rewardAmount+" and "+rewardType);
            });
        } else{
            Log.d(TAG, "The rewarded ad wasn't ready yet.");
        }

    }
Last edited by phoenix13032005 on Tue Mar 26, 2024 3:30 am, edited 1 time in total.

phoenix13032005
Newbie
Posts: 2
Joined: Sun Mar 03, 2024 3:02 pm
Contact:

Re: JavaException: JVM Exception occured: #008 Must be called on the main when calling a method from PythonSDLActivity.

#2 Post by phoenix13032005 »

I finally resolved all errors and it works as i intended. Just that it takes a bit of time to load so I have to push my textbutton once for the ad to load(takes 3-5 seconds as I can see from log cat) and once for the ad to show, I am thinking of cache-ing the ad when app starts and whenever an ad is shown. Will try to make a guide and tutorial on this topic on some later date when free.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], MisterPinetree