2017年4月29日土曜日

cocos2d-x <- android UIスレッドからの値の取得

cocos2d-xなどでAndroidのUIスレッドから値を直接取得したいという場合
例えば、 クリップボードから取得する場合とか
runOnUiThreadから処理したのちにcallbackを呼ぶ 必要があります

大変面倒なのでwaitを使ってブロッキング処理をしてみましょう
ということでBlockingOnUIRunnableを少し改良してGeneric型を返すようにしてみました


BlockingOnUIRunnable.java

 
/**
 * Blocking Runnable executing on UI thread
 *
 * @author
 *
 */
public class BlockingOnUIRunnable<t>
{
    // Activity
    private Activity activity;

    // Event Listener
    private BlockingOnUIRunnableListener<t> listener;

    // UI runnable
    private Runnable uiRunnable;

    public T retValue;

    /**
     * Class initialization
     * @param activity Activity
     * @param listener Event listener
     */
    public BlockingOnUIRunnable( Activity activity, BlockingOnUIRunnableListener<t> listener )
    {
        this.activity = activity;
        this.listener = listener;

        uiRunnable = new Runnable()
        {
            public void run()
            {
                // Execute custom code
                if ( BlockingOnUIRunnable.this.listener != null ) {
                    retValue = BlockingOnUIRunnable.this.listener.onRunOnUIThread();
                }

                synchronized ( this )
                {
                    this.notify();
                }
            }
        };
    }


    /**
     * Start runnable on UI thread and wait until finished
     */
    public void startOnUiAndWait()
    {
        synchronized ( uiRunnable )
        {
            // Execute code on UI thread
            activity.runOnUiThread( uiRunnable );

            // Wait until runnable finished
            try
            {
                uiRunnable.wait();
            }
            catch ( InterruptedException e )
            {
                e.printStackTrace();
            }
        }
    }

}
 
 
 

BlockingOnUIRunnableListener.java

 
/**
 * Events for blocking runnable executing on UI thread
 *
 * @author
 *
 */
public interface BlockingOnUIRunnableListener<t>
{

    /**
     * Code to execute on UI thread
     */
    public T onRunOnUIThread();
}


使い方 


BlockingOnUIRunnable<String> actionRunnable 
  = new BlockingOnUIRunnable<String>( {{context}}, new BlockingOnUIRunnableListener()
{
    public String onRunOnUIThread()
    {
        ClipboardManager clipboard = (ClipboardManager) {{context}}.getSystemService(Context.CLIPBOARD_SERVICE);
        if (clipboard.hasPrimaryClip()) {
            ClipData data = clipboard.getPrimaryClip();
            ClipDescription description = clipboard.getPrimaryClipDescription();
            if (data != null && description != null && description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN))
                return String.valueOf(data.getItemAt(0).getText());
        }
        
        return "";
    }
} );

actionRunnable.startOnUiAndWait();
return actionRunnable.retValue;
 
 
 
{{context}}はActivityのcontext, Cocos2dxActivity.getContext()等から取得する値 startOnUiAndWait()で処理を待って retValueから戻り値を取得します
wait中はGLThreadが停止するので重たい処理には使えません