【问题标题】:Execute transaction method using Realm continues to loop on each run android使用Realm执行事务方法在每次运行android上继续循环
【发布时间】:2018-01-17 10:18:01
【问题描述】:

在我的应用程序中,我使用 Realm DB 将所有数据存储在本地数据库中。我有一些初始模拟数据,我想在应用程序开始时显示它们。以前我实现了 begintransaction 方法。但是在阅读了文档后,我实现了执行交易方法。因为这种方法很容易更新我的新数据。现在的问题是,每当我单击显示recyclerview 的选项时,数据每次都在循环。例如我有 3 个数据。如果我回到上一页并再次进入这个 recyclerview 页面,它会变成双倍,下一次变成三倍,依此类推。我只想在视图中显示更新的数据。就像我添加第四个数据一样,我想将其显示给 recyclerview。如何在我的应用程序中停止每次运行时循环。

这是我的代码

个人页面

public class InitialData implements Realm.Transaction {
@Override
public void execute(Realm realm) {
    List<PersoneModel> person = new ArrayList<>();
    PersonModel model = new PersonModel();
    model.setId(1 + System.currentTimeMillis());
    model.setName("Name1");
    model.setCompany("Comapny1");
    model.setTitle("Title1");
    person.add(model);

    model = new PersonModel();
    model.setId(2 + System.currentTimeMillis());
    model.setName("Name2");
    model.setCompany("Company2");
    model.setTitle("Title2");
    person.add(model);

    model = new PersonModel();
    model.setId(2 + System.currentTimeMillis());
    model.setName("Name2");
    model.setCompany("Company2");
    model.setTitle("Title2");
    person.add(model);

    model = new PersonModel();
    model.setId(3 + System.currentTimeMillis());
    model.setName("Name3");
    model.setCompany("Comapny3");
    model.setTitle("Title3");
    person.add(model);

    for (PersonModel realmModel : colleague) {
        realm.insertOrUpdate(realmModel);
    }
}

@Override
public boolean equals(Object obj) {
    return obj != null && obj instanceof InitialData;
}

@Override
public int hashCode() {
    return InitialData.class.hashCode();
}

}

新闻页面初始数据

    public class InitialDataNews implements Realm.Transaction {
    @Override
    public void execute(Realm realm) {
    List<NewsModel> newsItem = new ArrayList<>();
    NewsModel model = new NewsModel();

    model.setId(1+System.currentTimeMillis());
    model.setImage(R.drawable.image1);
    model.setTitle("title1");
    model.setDate("12.07.2017");
    model.setDetail("deascription");
    newsItem.add(model);


    model = new NewsModel();
    model.setId(3+System.currentTimeMillis());
    model.setImage(R.drawable.image3);
    model.setTitle("title2");
    model.setDate("05.05.2017");
    model.setDetail("description");
    newsItem.add(model);

    model = new NewsModel();
    model.setId(4+System.currentTimeMillis());
    model.setImage(R.drawable.image4);
    model.setTitle("title3");
    model.setDate("13.04.2017");
    model.setDetail("description3");
    newsItem.add(model);


    .....


    for (NewsModel realmModel : newsItem) {
    realm.insertOrUpdate(realmModel);
    }
}
@Override
public boolean equals(Object obj) {
    return obj != null && obj instanceof InitialData;
}

@Override
public int hashCode() {
    return InitialData.class.hashCode();
  }

}

基础应用程序

 @Override
public void onCreate() {
    super.onCreate();
    // The Realm file will be located in Context.getFilesDir() with name "default.realm"
    //Here we setup the realm configuration.
    //Setting a default configuration in custom Application class, will ensure that it is available in the rest of the code.
    Realm.init(this);
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
        .deleteRealmIfMigrationNeeded()
        .initialData(CompositeInitialData.of(new InitialDataNews(), new InitialData()).build());
    Realm.setDefaultConfiguration(realmConfiguration);
  }

添加更改监听器

public class PersonPage extends AppCompatActivity implements PersonAdapter.PersonListListener{

private RecyclerView recyclerView;
private PersonAdapter adapter;
private Realm PersonRealm;
private RealmResults<PersoneModel> personResult;

private RealmChangeListener realmListener;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mycolleagues_layout);


    personRealm = Realm.getDefaultInstance();
    recyclerView = (RecyclerView) findViewById(R.id.colleagues_recycler);

    realmListener=new RealmChangeListener() {
        @Override
        public void onChange(Object o) {
            showAllPersons();
        }};
    colleagueRealm.addChangeListener(realmListener);

    setUpRecycler();
    }

 private void showAllPersons() {
    realmResult = personRealm.where(PersonModel.class).findAllAsync();
    setAdapter(realmResult);
    adapter.notifyDataSetChanged();
}

private void setAdapter(RealmResults<PersonModel> results) {

    adapter = new PersonAdapter(this, personRealm.where(PersonModel.class).findAllSortedAsync("id"),this);
    recyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}

【问题讨论】:

  • 您创建了new InitialData()new InitialDataPersons() 或类似的课程吗?
  • @EpicPanda for person my classname is InitialData.
  • 我建议然后更新问题
  • @EpicPanda 我已经给出了两个初始数据类
  • 它们是在自己的 java 文件中还是在另一个类中?如果他们在另一个班级,那么他们需要是public static class

标签: android android-recyclerview duplicates realm realm-mobile-platform


【解决方案1】:

那是因为在 onCreate() 中,您运行 basicCRUD(personRealm); 会添加新的人物模型

            PersonModel model = new PersonModel();
            model.setId(1 + System.currentTimeMillis());
            model.setName("Name1");
            model.setCompany("Comapny1");
            model.setTitle("Title1");
            person.add(model);

当您将 id 设置为 1 + System.currentTimeMillis() 时,它将是一个具有不同主键的新对象,并被插入。如果只是 12 等等,它会将它们更新为同一个对象。

值得庆幸的是,Realm 提供了initialData(Realm.Transaction) method on the RealmConfiguration.Builder(),它允许您仅在首次创建数据库时为数据库创建初始数据,或者在deleteRealmIfMigrationNeeded() 之后删除数据。

public class InitialData implements Realm.Transaction {
    @Override
    public void execute(Realm realm) {
        List<PersonModel> person = new ArrayList<>();
        PersonModel model = new PersonModel();
        model.setId(1 + System.currentTimeMillis());
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        person.add(model);

        model = new PersonModel();
        model.setId(2 + System.currentTimeMillis());
        model.setName("Name2");
        model.setCompany("Company2");
        model.setTitle("Title2");
        person.add(model);

        model = new PersonModel();
        model.setId(3 + System.currentTimeMillis());
        model.setName("Name3");
        model.setCompany("Company23");
        model.setTitle("Title3");
        person.add(model);

        model = new PersonModel();
        model.setId(4 + System.currentTimeMillis());
        model.setName("Name4");
        model.setCompany("Comapny4");
        model.setTitle("Title4");
        person.add(model);

        for (PersonModel realmModel : person) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Override
    public boolean equals(Object object) {
        return object != null && object instanceof InitialData;
    }

    @Override
    public int hashCode() {
        return InitialData.class.hashCode();
    }
}

Realm.init(this);
Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
                                    .deleteRealmIfMigrationNeeded()
                                    .initialData(new InitialData())
                                    .build());

编辑:

要在一个“初始数据”中提供多个“初始数据”(如您提供 1 个交易),您可以依靠 composite design pattern 在一个初始数据中提供多个初始数据,像这样

public final class InitialDataPersons implements Realm.Transaction {
    @Override
    public void execute(Realm realm) {
        List<PersonModel> person = new ArrayList<>();
        PersonModel model = new PersonModel();
        model.setId(1 + System.currentTimeMillis());
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        person.add(model);

        model = new PersonModel();
        model.setId(2 + System.currentTimeMillis());
        model.setName("Name2");
        model.setCompany("Company2");
        model.setTitle("Title2");
        person.add(model);

        model = new PersonModel();
        model.setId(3 + System.currentTimeMillis());
        model.setName("Name3");
        model.setCompany("Company23");
        model.setTitle("Title3");
        person.add(model);

        model = new PersonModel();
        model.setId(4 + System.currentTimeMillis());
        model.setName("Name4");
        model.setCompany("Comapny4");
        model.setTitle("Title4");
        person.add(model);

        for (PersonModel realmModel : person) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Override
    public boolean equals(Object object) {
        return object != null && object instanceof InitialDataPersons;
    }

    @Override
    public int hashCode() {
        return InitialDataPersons.class.hashCode();
    }
}

public final class InitialDataNews implements Realm.Transaction {
    @Override
    public void execute(Realm realm) {
        List<NewsModel> newsItem = new ArrayList<>();
        NewsModel model = new NewsModel();

        model.setId(1+System.currentTimeMillis());
        model.setImage(R.drawable.image1);
        model.setTitle("title1");
        model.setDate("12.07.2017");
        model.setDetail("deascription");
        newsItem.add(model);

        model = new NewsModel();
        model.setId(3+System.currentTimeMillis());
        model.setImage(R.drawable.image3);
        model.setTitle("title2");
        model.setDate("05.05.2017");
        model.setDetail("description");
        newsItem.add(model);

        model = new NewsModel();
        model.setId(4+System.currentTimeMillis());
        model.setImage(R.drawable.image4);
        model.setTitle("title3");
        model.setDate("13.04.2017");
        model.setDetail("description3");
        newsItem.add(model);

        .....

        for (NewsModel realmModel : newsItem) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && obj instanceof InitialDataNews;
    }

    @Override
    public int hashCode() {
        return InitialDataNews.class.hashCode();
    }
}

public final class CompositeInitialData implements Realm.Transaction {
    private final Realm.Transaction[] transactions;

    private CompositeInitialData(Realm.Transaction... transactions) { // `of` is prettier
        this.transactions = transactions;
    }

    public static CompositeInitialData of(Realm.Transaction... transactions) {
        return new CompositeInitialData(transactions);
    }

    @Override
    public void execute(Realm realm) {
        for(Realm.Transaction transaction : transactions) {
            transaction.execute(realm);
        }
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && obj instanceof CompositeInitialData; // you might want autogenerated equals instead
    }

    @Override
    public int hashCode() {
        return CompositeInitialData.class.hashCode(); // you might want autogenerated hashCode instead
    }
}

这样你就可以提供

Realm.init(this);
Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
             .deleteIfMigrationNeeded()
             .initialData(CompositeInitialData.of(new InitialDataNews(), new InitialDataPersons()))
             .build());

【讨论】:

  • 但我不想以这种方式实现初始数据。因为我有另一个页面,其中也有一些初始数据。有没有其他方法可以做到这一点。我也不想为此创建任何类
  • EpicPanda 对不起,你使用的语言,不是我对stackoverflow的期望。我尝试过使用初始数据。但我有两个数据作为初始数据。这样我就无法处理这个问题。可能对像你这样的“专家开发人员”来说更容易。
  • 是的。但是我面临的问题是我无法在配置中删除两个初始数据。为了避免这种情况,我在 Main activit 中创建了 public void basicCRUD(Realm realm) 并调用了 oncreate 方法。我有两个初始数据,一个是personinitila数据和news初始数据。我还没有找到在配置中声明两个初始数据的任何来源
  • 我为第二个初始数据创建了这个类。但我没有实现它
  • 这里的 CompositeInitialData 是什么意思。我也可以通过这种方式添加第三笔交易
猜你喜欢
  • 2015-07-26
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多