我是新來開發Android,我發現事件的流程相當混亂。Android中的事件流程
我想開發一個簡單的應用程序,每3秒拍一張照片並將其保存到外部存儲。我寫的(非常糟糕)的代碼看起來應該是繼這些事件序列:
button pressed > take photo > save photo > take photo > save photo > ...
而是它似乎是在做以下幾點:
button pressed > take photo > ... > take photo > save photo > ... > save photo
即節約大概所有的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;
}
}
如果需要,我可以提供ExternalStorage
的來源。
不要試圖睡在一個UI事件回調,或在ui線程的任何地方。您需要創建後臺線程或使用定時器或延遲發佈到處理程序的機制(如果要在活動處於前臺時執行此操作,或者如果要在活動時執行此操作,則需要使用服務中的線程)不是。 –