Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android中的事件流_Android_Multithreading_Camera - Fatal编程技术网

Android中的事件流

Android中的事件流,android,multithreading,camera,Android,Multithreading,Camera,我刚开始在android上开发,我发现事件的流程非常混乱 我正在尝试开发一个简单的应用程序,每3秒钟拍摄一张照片,并将其保存到外部存储。我编写的非常糟糕的代码看起来应该遵循以下事件序列: 按下按钮>拍照>保存照片>拍照>保存照片> 但它似乎在做以下事情: 按下按钮>拍照>…>拍照>保存照片>…>保存照片 i、 e.将所有照片保存在RAM中,然后在最后将它们全部写入磁盘,而不是在途中。对于大量图像,此操作失败 谁能给我指出正确的方向吗?这是我糟糕的代码: @SuppressWarnings("de

我刚开始在android上开发,我发现事件的流程非常混乱

我正在尝试开发一个简单的应用程序,每3秒钟拍摄一张照片,并将其保存到外部存储。我编写的非常糟糕的代码看起来应该遵循以下事件序列:

按下按钮>拍照>保存照片>拍照>保存照片>

但它似乎在做以下事情:

按下按钮>拍照>…>拍照>保存照片>…>保存照片

i、 e.将所有照片保存在RAM中,然后在最后将它们全部写入磁盘,而不是在途中。对于大量图像,此操作失败

谁能给我指出正确的方向吗?这是我糟糕的代码:

@SuppressWarnings("deprecation")
public class PhotoActivity extends Activity {

    Camera c = Camera.open();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photo);

        // Original, eh?
        final Button button = (Button)findViewById(R.id.button1);

        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                try {
                    // Fails for large i
                    for(int i = 0; i < 500; i++) {
                        // I don't think this is right.
                        Thread.sleep(1500);
                        takePictureNoPreviewAtAll(i);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void takePictureNoPreviewAtAll(int i) throws IOException, InterruptedException {
        // I don't know why this is 1, but it seems to work :)
        SurfaceTexture mTexture = new SurfaceTexture(1);
        c.setPreviewTexture(mTexture);
        c.startPreview();

        // This is not right either, but the camera seems to need both sleeps to work.
        Thread.sleep(1500);
        c.takePicture(null, null, getJpegCallback(i));
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_photo, menu);
        return true;
    }

    private android.hardware.Camera.PictureCallback getJpegCallback(final int i) {
        android.hardware.Camera.PictureCallback jpeg = new android.hardware.Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                try {
                    // Provided in a separate file, just saving to SD card, it seems to work.
                    Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations();
                    File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);

                    FileOutputStream f = new FileOutputStream(externalSdCard.getPath() + "/" + System.currentTimeMillis() + ".jpg");
                    f.write(data);
                    f.flush();
                    f.close();
                    Log.d(externalSdCard.getAbsolutePath(), "ddd");
                } catch (IOException e) {
                    //do something about it
                    e.printStackTrace();
                }
            }
        };
        return jpeg;
    }
}

如果需要,我可以提供外部存储的来源。

我宁愿等到回调完成它的工作,然后再拍其他照片。或者至少限制同时呼叫摄像头的次数,从而限制照片处理的次数。不确定它是否有助于消除所有等待,但至少它会使代码更加美观。

正如Chris所说,问题可能是您两次阻塞UI线程,您可以尝试使用计时器和TimerTask类


这样,代码将在不同的线程上执行。

不要尝试在ui事件回调中休眠,或者在ui线程中的任何位置休眠。如果希望在活动处于前台时创建后台线程或使用计时器等机制或延迟过帐到处理程序,或者如果希望在活动不处于前台时创建服务中的线程。
Timer timer = new Timer();
TimerTask cameraTask = new TimerTask() {
   public void run() {
      //Your camera code will be here.
   }
};
timer.schedule(cameraTask, 0, 1500);