2

我在 Android 中创建了 SQLite 数据库的备份,并希望将其同步到 Google Drive。备份未同步,以下代码没有错误:

public class Synchorize extends Activity {
    static final int REQUEST_ACCOUNT_PICKER = 1;
    static final int REQUEST_AUTHORIZATION = 2;
    private static Drive service;
    private static Uri fileUri;

    private GoogleAccountCredential credential;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.synchronize);
        credential = GoogleAccountCredential.usingOAuth2(this,
                Arrays.asList(DriveScopes.DRIVE));
        startActivityForResult(credential.newChooseAccountIntent(),
                REQUEST_ACCOUNT_PICKER);

    }

    @Override
    protected void onActivityResult(final int requestCode,
            final int resultCode, final Intent data) {
        switch (requestCode) {
        case REQUEST_ACCOUNT_PICKER:
            if (resultCode == RESULT_OK && data != null
                    && data.getExtras() != null) {
                String accountName = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                if (accountName != null) {
                    credential.setSelectedAccountName(accountName);
                    service = getDriveService(credential);
                    saveFileToDrive();

                }
            }
            break;
        }

    }

    private Drive getDriveService(GoogleAccountCredential credential) {
        return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
                new GsonFactory(), credential).build();
    }

    private void saveFileToDrive() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    // File's binary content
                    fileUri = Uri
                            .fromFile(new java.io.File(
                                    Environment.getDataDirectory().getPath()
                                            + "/data/com.example.note_taking/databases/notes.db"));
                    java.io.File fileContent = new java.io.File(fileUri.getPath());


                    FileContent mediaContent = new FileContent(getMimeType("db"), fileContent);

                    // File's metadata.
                    com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType(getMimeType("db"));

                    com.google.api.services.drive.model.File file = service
                            .files().insert(body, mediaContent).execute();
                    if (file != null) {
                        Toast.makeText(getApplicationContext(),
                                "Backup Uploaded Successfully",
                                Toast.LENGTH_LONG).show();
                        finish();

                    }
                } catch (UserRecoverableAuthIOException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
        t.start();
    }

    public String getMimeType(String url) {
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                url);
        return mimeType;
    }
}
4

1 回答 1

2

如果 SQLite 数据库没有通过连接(在任何进程中)保持打开状态,则它只是一个普通文件,可以像任何其他普通文件一样被复制。如果 SQLite 数据库通过连接保持打开状态,但没有正在进行的事务(尤其是没有更新),那么像这样备份它也应该没有问题。

事情变得可怕的地方是当您打开事务时,这些事务正在执行更新。特别是,您将依赖于能够使数据库在未来保持一致状态,尽管备份发生在“随机时间”相对于文件的写入。那是……不可取的。您最好连接、附加备份数据库文件、打开自己的事务,然后将事务中的数据复制到另一个数据库。然后,一旦您提交事务,您就可以安全地复制备份数据库文件,因为您可以相当确定没有其他任何东西会打开连接。这样做的主要缺点是您将在 DB 上打开一个相对较长的事务,但 SQLite 没有像 DB 服务器那样复杂的锁定模型,所以您被困住了;毕竟,获得进程内数据库的优势必须至少有一些缺点。

于 2013-10-19T14:27:55.990 回答