Closed lemon-juice closed 8 years ago
Thanks for the detailed explanation. Performance is definitely an issue that I would like to fix. I am hoping that by fixing #1 your issue here will also be resolved.
Even better optimization will be to move the Camera call on separate thread. Because initialization and releasing of the camera are slow operations. On my Nexus 5 they take about 1 second and Resuming and Pausing the Activity is slow. What I did additional to lemon-juice improvement is: BarcodeScannerView class -
public void stopCamera() {
if(mCamera != null) {
mPreview.setCamera(null, null);
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... params) {
if(mCamera != null) {
mCamera.cancelAutoFocus();
mCamera.setOneShotPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
return null;
}
}.execute();
}
}
and
CameraPreview class -
public void setCamera(Camera camera, Camera.PreviewCallback previewCallback) {
mCamera = camera;
mPreviewCallback = previewCallback;
mAutoFocusHandler = new Handler();
if(mCamera == null){
mPreviewing = false;
}
}
Fixed in v1.8.4. Basically Camera is opened in a HandlerThread. And the onPreviewFrame method no longer closes the camera. It only stops the camera preview. So in your handleResult method, if you would like to resume scanning you can do: mScannerView.resumeCameraPreview(this);
I have implemented your library in my application to scan QR codes and it is very good. However, I've come across one problem with the fact that after a code has been scanned (just before mResultHandler.handleResult() is called) your library stops the camera before returning to my code. In my application the handleResult() method needs to check if the scanned code is correct (has correct format) and only if it is I can accept it - otherwise I need to continue running the scanner until a correct code has been scanned.
First, the way I did it was that if the code was incorrect I restarted the scanner with mScannerView.startCamera() - no practical problem with that apart from a short camera freeze.
If the code was correct the procedure was like this:
I tested it on two phones - LG Swift L5 II performed very well, it took about 0.5 second from QR code recognition to seeing the confirmation screen. But then I tested it with Samsung Galaxy Xcover 3 and the same procedure was very slow - about 2.5 seconds. What I discovered was that in the Samsung stopping the camera before running handleResult() contributed to the delay - I saw the camera screen frozen for a while before the app proceeded to the confirmation screen. I have no idea why I experienced the delay in the Samsung since it is a newer and more powerful phone than the LG.
I managed to solve the problem and get rid of the delay by modifying your library not to stop the camera - the camera is only stopped in my app when leaving the scanner activity onPause() and now I was able to reduce the delay from 2.5 to about 0.5 second. Apart from not stopping the camera on code recognition my modifications were made to not continue with camera.setOneShotPreviewCallback() once the qr code was verified. Overall I think it would be good if your library did not stop the camera and left the control to the programmer.
What I did was I removed the stopCamera() in ZBarScannerView.java and modified the ResultHandler to return a boolean - if true is returned then ZBarScannerView is instructed to continue scanning (in case my app didn't accept the code), if it is false then ZBarScannerView will not continue scanning (if my app accepted the code and no longer needs the scanner and the camera to work). Here is my patch:
Of course, this may not be the best solution to change your library in this way because it is not backwards compatible - now handleResult() needs to return a boolean and the camera is not stopped so old code witll not work well with these changes. But you could implement some other way of achieving the same result, for example with a configuration variable and a different ResultHandler that will not stop the camera so an app developer can choose the alternative behaviour.