LoginSignup
2
2

More than 5 years have passed since last update.

cocos2d-xのtouchイベント内でtoastを表示したいとき。

Last updated at Posted at 2014-09-05

概要

メニューをタップ等したときに、例えば通信状態がよくない場合にエラーメッセージを出したいことがあると思いますが、JNI経由でToastを呼び出すと思わぬエラーが発生することがあります。
そういったときの対処方法のひとつを記載します。

環境

cocos2d-x(2.2.4)

原因

cocos2d-xのtouchイベントはGLThread内で処理されますが、Toastクラスは初期化時に内部でHandlerクラスの引数なしの初期化が行われており、この際に例外が送出されます。
例外が発生する該当箇所を見てみると、

Handler.java
public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

GLThread内でLooper.prepareがコールされていないようです。

対処方法

ここでは、Toastクラスの初期化がUIスレッド(mainスレッド)内で行われれば問題が発生しなさそうだということで、次のように記述してみました。

 //jni経由でコールされるメソッド
 Handler handler = new Handler(Looper.getMainLooper());
 handler.post(new Runnable(){
   public void run(){
     Toast toast = new Toast(
     
     toast.show();
   }
 });

かなり省略した感じですけどニュアンスは伝わると思います。
結局のところToastに限らず、touchイベント内でHandlerクラスを生成するケースがあれば全て同じ処理をする必要があります。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2