2013-08-01 2 views
1

Я реализую приложение с библиотекой OpenCV. После обработки входного кадра камеры я хочу обновить свой TextView. Тем не менее, я получаю следующее сообщение об ошибке:Не удается обновить пользовательский интерфейс (с использованием openCV) CalledFromWrongThreadException

08-01 17:01:45.085: E/AndroidRuntime(16284): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

Ниже упрощенный код моего приложения:

(...IMPORTS...) 
public class ObjectTracker extends Activity implements CvCameraViewListener2, OnClickListener { 

TextView resultTextView; 

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { 
    @Override 
    public void onManagerConnected(int status) { 
     switch (status) { 
      case LoaderCallbackInterface.SUCCESS: 
      { 
       Log.i(TAG, "OpenCV loaded successfully"); 
       myJavaCameraView.enableView(); 
      } break; 
      default: 
      { 
       super.onManagerConnected(status); 
      } break; 
     } 
    } 
}; 

public ObjectTracker() { 
    Log.i(TAG, "Instantiated new " + this.getClass()); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    (...) 
    resultTextView = (TextView)   
    findViewById(R.id.activity_object_tracker_native_textview_result); 
} 

@Override 
public void onPause() 
{ 
    super.onPause(); 
    if (myJavaCameraView != null) 
     myJavaCameraView.disableView(); 
} 

@Override 
public void onResume() 
{ 
    super.onResume(); 
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback); 
} 

public void onDestroy() { 
    super.onDestroy(); 
    if (myJavaCameraView != null) 
     myJavaCameraView.disableView(); 
} 

public void onCameraViewStarted(int width, int height) { 
} 

public void onCameraViewStopped() { 
} 

public Mat onCameraFrame(CvCameraViewFrame inputFrame) { 
    (...) 
    return trackFilteredObject(filteredFrame, newInputFrame); 
} 

public Mat trackFilteredObject(Mat filteredFrame, Mat inputFrame) 
{ 
    (...) 

    //HERE I WANT TO UPDATE MY TEXT VIEW 

    return inputImage; 
} 

}

Я не знаю, где я должен поставить код обновления, чтобы избавиться этой ошибки. Кто-нибудь может мне помочь?

ответ

4

Материал UI может быть изменен только из основной резьбы пользовательского интерфейса. И метод trackFilteredObject вашего обратного вызова (где вы обновляете свой TextView), очевидно, вызывается из фонового потока.

Чтобы решить эту проблему, вы можете использовать метод Activity#runOnUiThread, который позволяет публиковать исполняемый файл для выполнения в потоке пользовательского интерфейса.

Попробуйте заменить

//HERE I WANT TO UPDATE MY TEXT VIEW 

По

runOnUiThread(new Runnable() { 

    public void run() { 
     //HERE I WANT TO UPDATE MY TEXT VIEW 
    } 
}); 
+0

Ваше решение не работает. Я все еще получаю такое же исключение ... Может быть, проблема в методе onResume()? Любые другие идеи? – Marek

+0

Oki, я только что редактировал свой пример кода, чтобы он соответствовал вашим потребностям – fiddler

0

Я нашел решение:

public Mat trackFilteredObject(Mat filteredFrame, Mat inputFrame) 
{ 
    (...) 

    runOnUiThread(new Runnable() { 

     public void run() { 
      //HERE I UPDATE TEXT VIEW 
     } 
    }); 

    return inputImage; 
} 

Спасибо за помощь @fiddler

Смежные вопросы