2017-04-27 49 views
2

块I具有以下活性:如何保护的方法从与同步并行访问(){}在机器人

public class FaceActivity extends BiometricActivity implements CameraControlsListener 

此活动的onCreate方法如下:

controlsView = new CameraControlsView(this, this); 
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 

      controlsView.setLayoutParams(params); 
      layout.addView(controlsView); 

CameraControlsView类如下所示:

public class CameraControlsView extends LinearLayout { 

    // =========================================================== 
    // Public types 
    // =========================================================== 

    public interface CameraControlsListener { 
     void onSwitchCamera(); 

     void onChangeFormat(); 
    } 

    // =========================================================== 
    // Private fields 
    // =========================================================== 

    private CameraControlsListener mListener; 

    // =========================================================== 
    // Public constructor 
    // =========================================================== 

    public CameraControlsView(Context context, CameraControlsListener listener) { 
     super(context); 
     if (listener == null) throw new NullPointerException("listener"); 
     mListener = listener; 
     LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view = mInflater.inflate(R.layout.camera_controls, this, true); 
     ImageView switchCamera = (ImageView) view.findViewById(R.id.switch_camera); 
     switchCamera.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       synchronized (this) { 
        mListener.onSwitchCamera(); 
       } 
      } 
     }); 

     ImageView changeFormat = (ImageView) view.findViewById(R.id.change_format); 
     changeFormat.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mListener.onChangeFormat(); 
      } 
     }); 
    } 

} 

onSwitchCamera函数在FaceAcivity中被覆盖,该值为fo llows:

@Override 
    public void onSwitchCamera() { 
     if (!FacePreferences.isUseLiveness(this)) { 
      cancel(); 
      NCamera currentCamera = client.getFaceCaptureDevice(); 
      for (NDevice device : client.getDeviceManager().getDevices()) { 
       if (device.getDeviceType().contains(NDeviceType.CAMERA)) { 
        if (!device.equals(currentCamera)) { 
         client.setFaceCaptureDevice((NCamera) device); 
         startCapturing(); 
         break; 
        } 
       } 
      } 
     } 

    } 

当我按下按钮switchCamera onSwitchCamera函数被调用。当我多次点击它时,不等待摄像机改变并开始拍摄,可能会出现一些赛车状况,然后以某种方式不显示摄像机输出。所以我想通过同步(){}块来保护该方法免于并行访问。

我在switchCamera按钮的onClick方法中保留了syncronized关键字,但它不起作用。如何保护并行访问方法?

+0

如果不需要并发性,为什么不使用布尔值来等待第一个操作完成? –

+0

您是否可以禁用'switchCamera按钮',以便它不能被多次按下? –

+0

我想通过同步来保护并行访问方法(){} block –

回答

0

一般而言,您应该检查相机回调:使用相机回调(onActive,onClosed),您将知道何时启用该按钮才有意义。

您尝试使用​​没有什么意义,因为你需要同步的方式,但不访问相同的“软件”对象从不同的线程同时这个意思。您需要与相机驱动程序同步。

我的意思是启用相机两次都没有意义,只是等到它完成并提供再次禁用它的选项。

搜索您的createCaptureSession()呼叫并添加处理CameraCaptureSession.StateCallback中按钮的启用状态。

0

我想说一句,任何“同步”块都会影响性能,因为花费时间本身,并且锁定其他线程访问代码范围。此外,“同步”块导致大括号内的对象实例锁定。 “synchronized(this)”是一个错误的模式,因为锁定了整个实例。“同步”模块完成控制对资源的访问,这些资源可以被线程并发访问,并且必须提供对其更改的隔离。 所以你

synchronized (this) { 
    mListener.onSwitchCamera();     
} 

似乎出的原因,两次,考虑到它在构造函数中注入,而不是改变时服用。首先 - 同步(this)基本上不阻止任何人访问监听器:在你的情况下,这个是内联(lambda)类的一个实例,除了事件源(你的操作系统,就像我看到的,是Android,任何布局在UI线程中工作)。 其次,您尝试同步访问实例,该实例只能调用其函数(????)不可更改。没有竞争条件可能发生,因为函数在实例初始化之前绑定到类。如果你想同步Listener资源的访问权限,那么你必须在类的实例中做同样的事情,在相同的void onSwitchCamera()中。像这样,例如

@Override 
public void onSwitchCamera() 
{ 
    if (!FacePreferences.isUseLiveness(this)) { 
     cancel(); 
     synchronized(client) 
     { 
      NCamera currentCamera = client.getFaceCaptureDevice(); 
      for (NDevice device : client.getDeviceManager().getDevices()) { 
       if (device.getDeviceType().contains(NDeviceType.CAMERA)) { 
        if (!device.equals(currentCamera)) { 
         client.setFaceCaptureDevice((NCamera) device); 
         startCapturing(); 
         break; 
         } 
        } 
       } 
      } 
     } 

    } 

但是,您必须锁定仅存在竞争条件危险且仅存在危险时间的实例。

+0

按下ctrl + k按钮选择您的代码。 –

相关问题