5

OpenCV のカスタムである処理スレッドから Android トーストを作成する必要があるため、ここで提案されているように runOnUiThread() を使用できません: Android: Toast in a thread

このコードのほとんどは、CVCamera サンプル アプリからのものです。しかし、なじみのない方のために、Surf メニュー ボタンを選択すると、SURFProcessor が次のように呼び出されます。

           else if (item.getTitle().equals("SURF")) {

                   defaultcallbackstack.addFirst(new SURFProcessor());
                   toasts(DIALOG_TUTORIAL_SURF, "");

           }

このプロセッサ スレッドは、電話のカメラ ボタンを押すと (capturePress = true)、画像が撮影され、処理が完了するように実行されます。示されているように toasts メソッドを呼び出したい:

class SURFProcessor implements NativeProcessor.PoolCallback {

           @Override
           public void process(int idx, image_pool pool, long timestamp,
                           NativeProcessor nativeProcessor) {
                   if(capturePress) {
                           String processMsg = processor.processFeatures(idx, pool, cvcamera.DETECT_SURF);
                           capturePress = false;
                           toasts(PROCESS_MESSAGE, processMsg);
                   }
           }
}

Activity を拡張するメイン クラスにある toasts メソッドを次に示します。

void toasts(int id, String msg) {
           switch (id) {
           case PROCESS_MESSAGE:
                   Toast.makeText(MMRapp.this, msg, Toast.LENGTH_LONG).show();
                   break;
.........

現在、このコードは「Looper.prepare() を呼び出していないスレッド内でハンドラを作成できません」というエラーを表示します。toasts メソッドを呼び出すにはどうすればよいですか? または、toasts メソッドに processMsg の変更をリッスンさせることは可能ですか? 可能であれば、代わりに processMsg を送信するか、クラス変数を変更することで問題を解決できます。要するに、このプロセッサ スレッドから更新された文字列が必要です。

ありがとうございました。必要に応じて、より多くの情報/コードを提供します。
-トム

4

3 に答える 3

6

ハンドラーと実行可能なものを使用する アクティビティーでハンドラーと実行可能なものを作成します。

// these are members in the Activity class
Handler toastHandler = new Handler();
Runnable toastRunnable = new Runnable() {public void run() {Toast.makeText(Activity.this,...).show();}}

次に、スレッドの使用からそれを呼び出すには

toastHandler.post(toastRunnable);

ハンドラーは、作成されたスレッドでランナブルを実行します。

于 2011-03-22T02:09:14.647 に答える
1

ニーズに合ったオーバーロードを使用してください。

/**
 * Muestra un toast sin necesidad de preocuparse de estar en el hilo de la
 * UI o no.
 *
 * @param mContext
 * @param sMessage
 */
public static void showToast(final Context mContext, final int nMessageId) {
    if (Utils.isUiThread()) {
        Toast.makeText(mContext.getApplicationContext(), nMessageId, Toast.LENGTH_LONG).show();
        return;
    }
    Runnable mRunnableToast = new Runnable() {
        @Override
        public void run() {
            Toast.makeText(mContext.getApplicationContext(), nMessageId, Toast.LENGTH_LONG).show();
        }
    };
    if (mContext instanceof Activity) {
        ((Activity) mContext).runOnUiThread(mRunnableToast);
        return;
    }
    Utils.runOnUiThread(mRunnableToast);
}

/**
 * Muestra un toast sin necesidad de preocuparse de estar en el hilo de la
 * UI o no.
 *
 * @param mContext
 * @param sMessage
 */
public static void showToast(final Context mContext, final CharSequence sMessage) {
    if (Utils.isUiThread()) {
        Toast.makeText(mContext.getApplicationContext(), sMessage, Toast.LENGTH_LONG).show();
        return;
    }
    Runnable mRunnableToast = new Runnable() {
        @Override
        public void run() {
            Toast.makeText(mContext.getApplicationContext(), sMessage, Toast.LENGTH_LONG).show();
        }
    };
    if (mContext instanceof Activity) {
        ((Activity) mContext).runOnUiThread(mRunnableToast);
        return;
    }
    Utils.runOnUiThread(mRunnableToast);
}

public static boolean isUiThread() {
    Looper mCurrentLooper = Looper.myLooper();
    if (mCurrentLooper == null) {
        return false;
    }
    if (mCurrentLooper.equals(Looper.getMainLooper())) {
        return true;
    }
    return false;
}

public static void runOnUiThread(Runnable mRunnable, Context mContext) {
    if (mContext instanceof Activity) {
        runOnUiThread(mRunnable, (Activity) mContext);
    } else {
        Utils.runOnUiThread(mRunnable);
    }
}

public static void runOnUiThread(Runnable mRunnable, View vView) {
    if (Utils.isUiThread()) {
        mRunnable.run();
    } else {
        vView.post(mRunnable);
    }
}

public static void runOnUiThread(Runnable mRunnable, Activity mActivity) {
    if (mActivity != null) {
        mActivity.runOnUiThread(mRunnable);
    } else {
        Utils.runOnUiThread(mRunnable);
    }
}

public static void runOnUiThread(Runnable mRunnable) {
    if (Utils.isUiThread()) {
        mRunnable.run();
    } else {
        Handler mUiHandler = new Handler(Looper.getMainLooper());
        mUiHandler.post(mRunnable);
    }
}
于 2016-07-06T10:59:26.850 に答える