1

我正在编写一个应用程序,它应该具有以下用例:用户单击“开始!” 按钮,应用程序开始每 1 分钟单击一次图片(在内部使用 CameraPreview 类),并将按钮文本更改为“完成!”。

当用户按下相同的按钮(但带有新的按钮文本“完成!”)时,应用程序应该停止。

当用户单击“开始!”时,我已经能够编写每分钟单击一次图片的代码!按钮。但是,一旦图像捕获开始,按钮就会冻结。

如何以按钮不会冻结的方式运行我的每 1 分钟图像捕获逻辑?围绕它的最佳实践是什么?谢谢!

这是 OnClick() 的代码:

    @Override
public void onClick(View v) {
    Button button = (Button)v;
    String buttonText = button.getText().toString();

    if(buttonText.equals(Constant.trainButtonText)) {
        Log.i(TAG, "Robot Training started...");

        while(true) {
            surfaceView.capture(new Camera.PictureCallback() {
                public void onPictureTaken(byte[] data, Camera camera) {
                    Log.v("Still", "Image data received from camera");

                    String[] params = new String[] {
                            Constant.Server, // Server URL
                            Long.toString(new Date().getTime()), // Image Timestamp
                            Constant.userId // Unique user ID for each customer
                    };
                    new UploadImageToWebServiceTask(data).execute(params);
                    camera.startPreview();
                }
            });
            try {
                // Capture every 1 minute until 'training done!' is not clicked
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    else if(buttonText.equals(Constant.doneTrainingButtonText)) {
        Log.i(TAG, "Robot Training completed...");
        button.setText(Constant.trainButtonText);
        button.clearFocus();
    }
}

在代码中使用了相同的按钮 - 只是我们根据按钮文本决定要做什么。

4

1 回答 1

2

不要阻塞 UI 线程,切换到 Runnable。此外,您每秒都在拍照:1000是一秒,60000是一分钟。

首先创建一个新的字段变量:

public class MainActivity extends Activity {
    Runnable takePictures = new Runnable() {
        @Override
        public void run() {
            // I'll trust that this code works
            surfaceView.capture(new Camera.PictureCallback() {
                public void onPictureTaken(byte[] data, Camera camera) {
                    Log.v("Still", "Image data received from camera");

                    String[] params = new String[] {
                            Constant.skynetNNServer, // Server URL
                            Long.toString(new Date().getTime()), // Image Timestamp
                            Constant.userId // Unique user ID for each customer
                    };
                    new UploadImageToCloudTask(data).execute(params);
                    camera.startPreview();
                }
            });

            // Call this runnable again in 60 seconds (60000 milliseconds) 
            surfaceView.postDelayed(this, 60000);
        }
    };
    // Rest of your code

然后改变你的onClick方法:

@Override
public void onClick(View v) {
    Button button = (Button)v;
    String buttonText = button.getText().toString();

    if(buttonText.equals(Constant.trainButtonText)) {
        Log.i(TAG, "Robot Training started...");
        surfaceView.post(takePictures);
    }
    else if(buttonText.equals(Constant.doneTrainingButtonText)) {
        Log.i(TAG, "Robot Training completed...");
        surfaceView.removeCallbacks(takePictures);
        button.setText(Constant.trainButtonText);
        button.clearFocus();
    }
}
于 2012-12-02T06:35:04.347 回答