2011-03-22 7 views
5

मुझे एक प्रोसेसिंग थ्रेड से एंड्रॉइड टोस्ट बनाने की ज़रूरत है, जो ओपनसीवी के लिए कस्टम है, इसलिए मैं runOnUiThread() का उपयोग नहीं कर सकता जैसा कि यहां सुझाया गया है: Android: Toast in a threadकिसी अन्य धागे से टोस्ट बनाने के लिए कैसे करें (sans runOnUiThread)

इनमें से अधिकांश कोड CVCamera नमूना ऐप से है। लेकिन उन अपरिचित, जब मैं सर्फ मेनू बटन का चयन करें, SURFProcessor तो जैसे कहा जाता है:

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

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

      } 

यह प्रोसेसर धागा इतना है कि जब मैं फ़ोन के कैमरे बटन दबाएँ (capturePress = सच), एक छवि लिया जाता है चलाया जाता है और प्रसंस्करण किया। मैं दिखाया गया है टोस्ट विधि कॉल करना चाहते हैं:

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

अभी इस कोड को मुझे एक त्रुटि देता है:

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); 
        } 
      } 
} 

यहाँ टोस्ट विधि, मुख्य वर्ग में स्थित विस्तार गतिविधि है "नहीं कर सकते थ्रेड के अंदर हैंडलर बनाएं जिसे Looper.prepare() नहीं कहा जाता है। " टोस्ट्स विधि को कॉल करने के बारे में मैं कैसे जा सकता हूं? या क्या प्रक्रियाओं में बदलाव के लिए टोस्ट विधि सुनना संभव है? यदि संभव हो, तो मैं प्रक्रिया संदेश भेजने या इसके बजाय कक्षा चर बदलने के साथ प्राप्त कर सकता हूं। संक्षेप में, मुझे इस प्रोसेसर थ्रेड से अपडेट की गई स्ट्रिंग की आवश्यकता है।

बहुत बहुत धन्यवाद, और यदि चाहें तो मैं अधिक जानकारी/कोड प्रदान करूंगा।
टॉम

उत्तर

6

उपयोग हैंडलर और एक runnable हैंडलर और runnable गतिविधि में बनाओ:

// 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); 

हैंडलर कार्यान्वित धागे में चलने योग्य यह बनाया गया था।

+0

धन्यवाद! एक आकर्षण की तरह काम करता है ... मुझे लगा कि इसे करने का एक आसान तरीका होना चाहिए। – wrapperapps

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

इस प्रश्न और आपके उत्तर को पढ़ने वाले अन्य लोगों के लाभ के लिए, क्या आप इस समस्या को हल करने के तरीके के बारे में अधिक विशिष्ट हो सकते हैं? मूल पोस्टर से पूछे जाने वाले मामले के लिए इनमें से किस का उपयोग किया जाना चाहिए? –

+1

अच्छा, यह बहुत आसान है। ओपी की समस्या यह है कि वह यूआई थ्रेड के बाहर टोस्ट पोस्ट करने की कोशिश कर रहा है और इसकी अनुमति नहीं है। मेरा स्निपेट उस पर ख्याल रखता है। किस ऑब्जेक्ट के आधार पर उसके पास उसके कोड (ब्रॉडकास्ट रिसीवर संदर्भ, एक गतिविधि, एक अनुप्रयोग, आदि) तक पहुंच है, वह एक या अन्य अधिभार का उपयोग कर सकता है। शायद यह एक: 'सार्वजनिक स्थैतिक शून्य शो टोस्ट (अंतिम संदर्भ mContext, अंतिम CharSequence sMessage) ' – Reaper

+0

यह विस्तार बहुत उपयोगी है। इस पर विस्तार के लिए धन्यवाद! –

0

प्रसारण प्रेषक का उपयोग क्यों न करें?
लिखें यह

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(); 
     } 
    } 
} 

परिभाषित करें यह

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

उत्प्रेरक यह

public void showMessage(String message) { 
    Intent intent = new Intent(); 
    intent.setAction(getPackageName() + ".TOAST"); 
    intent.putExtra(ToastTrigger.EXTRA_MESSAGE, message); 
    sendBroadcast(intent); 
} 
संबंधित मुद्दे