2011-03-22 18 views
5

Bir OpenCV için özel olan bir işlem parçacığından bir Android tost yapmam gerekiyor, bu yüzden burada önerildiği gibi runOnUiThread() kullanamazsınız: Android: Toast in a thread.başka bir iş parçacığı üzerinden tost nasıl yapılır (sans runOnUiThread)

Bu kodun çoğu CVCamera örnek uygulamasından alınmıştır. Oynarım menü düğmesini seçin Ama bu alışılmadık, SURFProcessor şöyle denir:

Ben telefonun kamera düğmesine bastığınızda (= true capturePress), bir görüntü alınır ve böylece bu İşlemci iplik çalıştırılır
  else if (item.getTitle().equals("SURF")) { 

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

      } 

ve işlem tamamlandı. gösterildiği gibi ben tost yöntemi çağırmak istiyorum:

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

şimdi bu kod bana bir hata veriyor:

İşte
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); 
        } 
      } 
} 

ana sınıfında bulunan tost yöntem uzanan Hareketi "olamaz Looper.prepare() adı verilen iş parçacığı içinde işleyici oluştur. Tost yöntemini çağırmaya nasıl giderim? Veya tost yönteminin processMsg'de bir değişiklik için dinlenmesi mümkün mü? Mümkünse, processMsg göndererek veya bir sınıf değişkenini değiştirerek yapabilirim. Özünde, bu İşlemci iş parçacığından güncellenmiş bir Dize ihtiyacım var.

Çok teşekkür ederim ve istenirse daha fazla bilgi/kod sağlayacağım.

toastHandler.post(toastRunnable); 

işleyicisi yürütür senin iplik kullanımından onu çağırmak için daha sonra

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

:
-Tom

cevap

6

kullanımı bir işleyici ve çalıştırılabilir aktivitesinde Handler ve yürütülebilir olun Oluşturulduğu iş parçacığı içinde çalıştırılabilir.

+0

teşekkür ederim o

<receiver android:name=".receivers.ToastTrigger" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="com.example.TOAST" /> </intent-filter> </receiver> 

Tetik tanımlayın! Bir çekicilik gibi çalışır ... Bunu yapmak için basit bir yol olması gerektiğini düşündüm. – wrapperapps

1

Gereksinimlerinize uygun aşırı yükü kullanın.

/** 
* 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); 
    } 
} 
+0

Bu soruyu ve cevabınızı okuyan başkalarının yararı için, sorunun nasıl çözüldüğü konusunda daha spesifik olabilir misiniz? Orijinal posterin sorusu için hangisinin kullanılması gerekir? –

+1

Eh, oldukça basit. OP'nin problemi, UI dizisi dışında tost yayınlamaya çalışıyor olması ve buna izin verilmemesi. Snippet'im bununla ilgileniyor. Hangi nesnenin kendi kodunda (BroadcastReceiver içeriği, Etkinlik, Uygulama, vb.) Varlığına bağlı olarak, bir veya daha fazla aşırı yükü kullanabilir. Belki bu biri: 'public statik void showToast (son Bağlam mContext, son CharSequence sMessage)' – Reaper

+0

Bu ayrıntı çok yararlıdır. Bunu genişlettiğiniz için teşekkürler! –

0

Neden bir yayın alıcısı kullanmıyoruz?
Yaz o

public class ToastTrigger extends BroadcastReceiver { 

    public static final String EXTRA_MESSAGE = "message"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Timber.d("ToastTrigger: received"); 
     if (intent.hasExtra(EXTRA_MESSAGE)) { 
      Toast.makeText(context, intent.getStringExtra(EXTRA_MESSAGE), Toast.LENGTH_SHORT) 
       .show(); 
     } 
    } 
} 

o

public void showMessage(String message) { 
    Intent intent = new Intent(); 
    intent.setAction(getPackageName() + ".TOAST"); 
    intent.putExtra(ToastTrigger.EXTRA_MESSAGE, message); 
    sendBroadcast(intent); 
} 
İlgili konular