以下代码在新线程内运行。
private class SaveUserTask extends AsyncTask<User, Void, Void> {
@Override
protected Void doInBackground(User... users) {
DatabaseHandler dbHandler = new DatabaseHandler(LoginActivity.this);
dbHandler.createUser(users[0]);
return null;
}
}
构造它并运行它的代码在回调方法中。
private class GraphCallbackHandler implements Request.GraphUserCallback {
@Override
public void onCompleted(GraphUser gUser, Response response) {
if (gUser != null) {
id = gUser.getId().trim();
DatabaseHandler dbHandler = new DatabaseHandler(
LoginActivity.this);
if (!dbHandler.isFacebookIdAlreadyStored(id)) {
SaveUserTask suTask = new SaveUserTask();
User user = new User();
user.setUsername(gUser.getUsername().trim());
user.setFacebookId(id);
if (email != null)
user.setEmail(emailStr.trim());
suTask.execute(user);
}
}
看起来两次调用回调方法会导致两个相同的行插入表中。有没有办法阻止回调方法被调用两次(这对我来说似乎不太可能实现)或停止后台任务运行两次?
答案 0 :(得分:2)
只需执行以下步骤:
doInBackground
方法。doInBackground
LOCK设置synchronized
方法代码Object
。或者您可以将已保存的用户存储到内存中HashSet
之类的对象,并在插入db之前检查是否存在。
请注意,在这种情况下使用数据库的某些位置必须是线程安全的或同步的。否则,你可能会遇到这样的问题。
答案 1 :(得分:1)
如果onCompleted
在短时间内拨打两次,我认为你只有一个典型的竞争条件:
快乐的道路:
并且它可以在另一个顺序中工作,因为线程并行工作:
我认为最好的解决方案是移动(或复制)支票,以便异步操作应该进行检查以进行操作idempotent。