Android:Parse.com 与 findInBackground() 的并发问题 [英] Android: Parse.com concurrency issue with findInBackground()

查看:48
本文介绍了Android:Parse.com 与 findInBackground() 的并发问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Parse.com 作为我的应用程序的后端.Parse的本地数据库好像很好用,所以我决定用它.

I am using Parse.com as a backend for my app. The local database from Parse seems to be very easy to use, so I decided to use it.

我想用NamePhoneNumber 创建一个数据库.这很简单,只需创建一个 new ParseObjectpinInBackground().但是当我想删除重复的数字时,它会更复杂.首先,我需要搜索数据库中是否已存在该号码,如果不存在则添加新号码.

I want to create a database with Name and PhoneNumber. That is easy, just make a new ParseObject and pinInBackground(). But it is more complicated when I want to remove duplicate numbers. First I need to search if the number already exists in the database and then add the new number if it doesn't exists.

这样做的方法是:

 public void putPerson(final String name, final String phoneNumber, final boolean isFav) {

    // Verify if there is any person with the same phone number
    ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseClass.PERSON_CLASS);
    query.whereEqualTo(ParseKey.PERSON_PHONE_NUMBER_KEY, phoneNumber);
    query.fromLocalDatastore();
    query.findInBackground(new FindCallback<ParseObject>() {
                               public void done(List<ParseObject> personList,
                                                ParseException e) {
                                   if (e == null) {
                                       if (personList.isEmpty()) {
                                           // If there is not any person with the same phone number add person
                                           ParseObject person = new ParseObject(ParseClass.PERSON_CLASS);
                                           person.put(ParseKey.PERSON_NAME_KEY, name);
                                           person.put(ParseKey.PERSON_PHONE_NUMBER_KEY, phoneNumber);
                                           person.put(ParseKey.PERSON_FAVORITE_KEY, isFav);

                                           person.pinInBackground();
                                       } else {
                                           Log.d(TAG, "Warning: " + "Person with the number " + phoneNumber + " already exists.");
                                       }
                                   } else {
                                       Log.d(TAG, "Error: " + e.getMessage());
                                   }
                               }
                           }
    );

}

假设我想在数据库中添加 3 个人:

Lets say I want to add 3 persons in the database:

    ParseLocalDataStore.getInstance().putPerson("Jack", "0741234567", false);
    ParseLocalDataStore.getInstance().putPerson("John", "0747654321", false);
    ParseLocalDataStore.getInstance().putPerson("Jack", "0741234567", false);
    ParseLocalDataStore.getInstance().getPerson(); // Get all persons from database

注意第一人称和第三人称数字相同,所以第三人不会被添加到数据库中,但是...

Notice that first and third person have the same number so the third souldn't be added to database, but...

后面的logcat是:

12-26 15:37:55.424 16408-16408/D/MGParseLocalDataStore: Person:0741234567 was added.
12-26 15:37:55.424 16408-16408/D/MGParseLocalDataStore: Person:0747654321 was added.
12-26 15:37:55.484 16408-16408/D/MGParseLocalDataStore: Person:0741234567 was added.
12-26 15:37:55.494 16408-16408/D/MGParseLocalDataStore: Person database is empty

logcat 的最后一行来自显示数据库中所有人的方法:

The last line from logcat is from the method that shows me all persons from database:

public void getPerson() {
        ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseClass.PERSON_CLASS);
        query.fromLocalDatastore();
        query.findInBackground(new FindCallback<ParseObject>() {
            public void done(List<ParseObject> personList,
                             ParseException e) {
                if (e == null) {
                    if (personList.isEmpty()) {
                        Log.d(TAG, "Person database is empty");
                    } else {
                    for (ParseObject p : personList) {
                        Log.d(TAG, p.getString(ParseKey.PERSON_PHONE_NUMBER_KEY));
                    }
                }
            } else {
                Log.d(TAG, "Error: " + e.getMessage());
            }

        }
    });
}

所以有两个问题:

  1. 即使我检查了是否已经存在,也会添加第三个数字.

  1. The third number is added even if I checked if already exists.

显示所有人的方法告诉我我的数据库中没有任何内容,即使在 logcat 中我可以看到它添加了 3 个人.

The method that shows me all persons tell me I have nothing in my database even if in logcat I can see it added 3 persons.

我认为问题在于在另一个线程中完成所有工作的 findInBackground() 方法.这个问题有什么解决办法吗?

推荐答案

您的两个问题都是异步工作的结果.如果您两次调用 putPerson 方法,它们将几乎同时在单独的后台线程中运行,并且两个查找查询很可能几乎同时返回,而且肯定是在第一次调用保存之前新人.

Both of your problems are a result of asynchronous work. If you call the putPerson method twice, they will both run near-simultaneously in separate background threads and both find-queries will most likely return almost at the same time, and definitely before the first call has saved the new person.

在您的示例中,getPerson 调用将在后台线程也能够拯救您的三个人之前返回.

In your example, the getPerson call will return before the background threads have been able to save your three people as well.

您的问题实际上与 Parse 或 localDataStore 无关,而是典型的并发问题.您需要重新考虑如何处理应用程序中的并发性.

Your problem is not really related to Parse or localDataStore, but is a typical concurrency issue. You need to rethink how you handle concurrency in your app.

只要这只是局部问题,您可以使用 Bolts 框架 强加同步结构a> (因为您使用的是 Parse,它已经是您的应用程序的一部分).但是如果对 addPerson 的调用在多个地方完成,您将始终面临这个问题,您必须找到其他解决方案或变通方法来处理并发.

As long as this is only a local issue, you can impose synchronous structure with i.e. the Bolts Framework (which is already a part of your app since you're using Parse). But if calls to addPerson is done in multiple places, you will always face this problem and you'd have to find other solutions or workarounds to handle concurrency.

并发是一个很大的话题,你应该花一些时间研究.

Concurrency is a big topic which you should spend some time studying.

这篇关于Android:Parse.com 与 findInBackground() 的并发问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆