在opencv for android(runOnUiThread)中禁用和启用按钮功能
如何在opencv for android中实现按钮禁用和启用功能。我跟随帖子,在surfaceview上显示了一个按钮。现在,如果我尝试禁用这个按钮或使用在opencv for android(runOnUiThread)中禁用和启用按钮功能,android,multithreading,opencv,button,Android,Multithreading,Opencv,Button,如何在opencv for android中实现按钮禁用和启用功能。我跟随帖子,在surfaceview上显示了一个按钮。现在,如果我尝试禁用这个按钮或使用 btnOK.setEnabled(false); or btnOK.setVisibility(View.INVISIBLE); 它会抛出一个错误 E/AndroidRuntime(24225): android.view.ViewRootImpl$CalledFromErrorThreadException:只有 创建视图层次结构的原始
btnOK.setEnabled(false); or btnOK.setVisibility(View.INVISIBLE);
它会抛出一个错误
E/AndroidRuntime(24225):
android.view.ViewRootImpl$CalledFromErrorThreadException:只有
创建视图层次结构的原始线程可以接触其视图
public class Tutorial2Activity扩展活动实现了CvCameraViewListener2,OnTouchListener{
私人医疗设备;
私人马拉松;
私人按钮学习按钮;
私有易失性线程btnthread;
私人MenuItem mItemPreviewLearn;
私人MenuItem mItemPreviewFeatures;
私人MenuItem mItemPreviewMatcher;
创建时的公共void(Bundle savedInstanceState){
Log.i(标记“calledoncreate”);
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG\u保持屏幕打开);
setContentView(R.layout.tutorial2_surface_视图);
mOpenCvCameraView=(CameraBridgeViewBase)findViewById(R.id.tutorial2\u活动\u表面\u视图);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(本);
ArrayList视图=新建ArrayList();
添加(findviewbyd(R.id.learnbutton));
learnbutton=(按钮)findViewById(R.id.learnbutton);
mOpenCvCameraView.addTouchables(视图);
}
@凌驾
公共布尔onCreateOptions菜单(菜单菜单){
mItemPreviewFeatures=menu.add(“查找特征”);
mItemPreviewLearn=menu.add(“学习对象”);
mItemPreviewMatcher=menu.add(“查找匹配”);
返回true;
}
@凌驾
公共无效暂停()
{
super.onPause();
if(mOpenCvCameraView!=null)
mOpenCvCameraView.disableView();
}
@凌驾
恢复时公开作废()
{
super.onResume();
initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,this,mLoaderCallback);
}
公共空间{
super.ondestory();
if(mOpenCvCameraView!=null)
mOpenCvCameraView.disableView();
}
开始时的公共空隙(整数宽度、整数高度){
mRgba=新垫(高度、宽度、CvType.CV_8UC4);
mIntermediateMat=新垫(高度、宽度、CvType.CV_8UC4);
mGray=新垫(高度、宽度、CvType.CV_8UC1);
}
CAMERAVIEWSTOPPED()上的公共空白{
mRgba.release();
mGray.release();
mIntermediateMat.release();
}
CameraFrame上的公用Mat(CvCameraViewFrame输入框){
最终int viewMode=mViewMode;
开关(查看模式){
案例视图\模式\学习:
//使按钮在此处不可见
//设置可见性(View.GONE);
//learnbutton.setEnabled(false);
//设置可见性(视图不可见);
runThread();
mRgba=inputFrame.rgba();
打破
案例视图\模式\功能:
//在这里启用按钮
打破
案例视图\模式\匹配器:
//在这里启用按钮
打破
}
返回mRgba;
}
私有void runThread()
{
btnthread=新线程(){
公开募捐{
{
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
设置可见性(View.VISIBLE);
}
});
}
}
};
btnthread.start();
}
}
我刚刚尝试了btnOK.setVisibility(View.INVISIBLE)代码>工作正常。使用“runonUIThread”android功能在单独的线程中执行此操作我尝试使用单独的runonUIThread,速度非常慢,在按钮设置为可见之前需要花费大量时间。此外,如果我在菜单之间切换,它将不起作用,即如果按钮被启用或禁用,它将在所有三个菜单选项中继续这样做。我已经用我的代码更新了这个问题。问题是onCameraFrame方法在UI线程之外运行,我必须在那里进行修改。我尝试了btnOK.setVisibility(View.INVISIBLE);在这个方法之外,也就是oncreate方法,它工作得非常好
public class Tutorial2Activity extends Activity implements CvCameraViewListener2,OnTouchListener{
private Mat mIntermediateMat;
private Mat mGray;
private Button learnbutton;
private volatile Thread btnthread;
private MenuItem mItemPreviewLearn;
private MenuItem mItemPreviewFeatures;
private MenuItem mItemPreviewMatcher;
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial2_surface_view);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial2_activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
ArrayList<View> views = new ArrayList<View>();
views.add(findViewById(R.id.learnbutton));
learnbutton=(Button)findViewById(R.id.learnbutton);
mOpenCvCameraView.addTouchables(views);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mItemPreviewFeatures = menu.add("Find features");
mItemPreviewLearn = menu.add("Learn object");
mItemPreviewMatcher = menu.add("Find Match");
return true;
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat(height, width, CvType.CV_8UC4);
mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
mGray = new Mat(height, width, CvType.CV_8UC1);
}
public void onCameraViewStopped() {
mRgba.release();
mGray.release();
mIntermediateMat.release();
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
final int viewMode = mViewMode;
switch (viewMode) {
case VIEW_MODE_LEARN:
// make button invisible here
//learnbutton.setVisibility(View.GONE);
//learnbutton.setEnabled(false);
//learnbutton.setVisibility(View.INVISIBLE);
runThread();
mRgba = inputFrame.rgba();
break;
case VIEW_MODE_FEATURES:
//enable the button here
break;
case VIEW_MODE_MATCHER:
//enable the button here
break;
}
return mRgba;
}
private void runThread()
{
btnthread = new Thread() {
public void run() {
{
runOnUiThread(new Runnable() {
@Override
public void run() {
learnbutton.setVisibility(View.VISIBLE);
}
});
}
}
};
btnthread.start();
}
}