Reputation: 195
guys i retrieve from outside database (using retrofit) many (6600 rows) of object which looks and works with my POJO class. After that i try to put it into Realm object but its very slow. I suspect that this slow action is because i begin i commit transaction row by row. Maybe anybody know how to put full arraylist to realm object in one commit? My Main:
private class AsyncTaskRetro extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
PlacesAPI.Factory.getInstance().getPlaces().enqueue(new Callback<Places>() {
@Override
public void onResponse(Call<Places> call, Response<Places> response) {
for (int i = 0; i < response.body().getPosts().size(); i++) {
RowModel rowModel = new RowModel(response.body().getPosts().get(i).getNazwa(),
Double.parseDouble(response.body().getPosts().get(i).getSzer()),
Double.parseDouble(response.body().getPosts().get(i).getDlug()));
rowModels.add(rowModel);
}
String oldName;
oldName = rowModels.get(0).getName();
shopsNames.add(rowModels.get(0).getName());
mRealm.beginTransaction();
RowModel rowModelRealm = mRealm.createObject(RowModel.class);
mRealm.commitTransaction();
for (int j = 0; j < rowModels.size(); j++) {
mRealm.beginTransaction();
rowModelRealm.setName(rowModels.get(j).getName());
rowModelRealm.setLattitude(rowModels.get(j).getLattitude());
rowModelRealm.setLongitude(rowModels.get(j).getLongitude());
mRealm.commitTransaction();
if (rowModels.get(j).getName().equals(oldName)) {
continue;
}
oldName = rowModels.get(j).getName();
shopsNames.add(rowModels.get(j).getName());
}
//sortowanie
listy z nazwami sklepow
Collections.sort(shopsNames);
adapter = new ShopsAdapter(MainActivity.this, shopsNames);
recyclerView.setAdapter(adapter);
}
@Override
public void onFailure(Call<Places> call, Throwable t) {
}
});
return null;
}
}
and POJO:
public class RowModel extends RealmObject {
@Required
private String name;
@Required
private Double lattitude, longitude;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getLattitude() {
return lattitude;
}
public void setLattitude(Double lattitude) {
this.lattitude = lattitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public RowModel(String name, Double lattitude, Double longitude) {
this.name = name;
this.lattitude = lattitude;
this.longitude = longitude;
}
public RowModel() {
}
}
Upvotes: 1
Views: 846
Reputation: 81539
1.) you're using Realm 0.82.2, and that version has quirks which is why the next stable version I recommend is 0.87.5; but in reality the latest stable version (at the moment) is 3.1.4.
You should probably switch to a version that isn't 2 years old?
2.) You are running an AsyncTask, but you use enqueue
in it:
getPlaces().enqueue(new Callback<Places>() {
@Override
public void onResponse(Call<Places> call, Response<Places> response) {
This means that Retrofit callback will execute on UI thread.
Then, you do synchronous transactions, so you're writing to Realm on the UI thread, which is bad.
3.) you're trying to manually sort the downloaded elements and then showing them in the adapter also manually, which doesn't make sense if you're using Realm, because Realm allows sorting elements by a particular field. Also shopsNames
is definitely not a RealmResults, meaning you aren't even listening for changes made to the DB.
ShopsAdapter
should be a RealmBaseAdapter
.
So the code should be more like this
private class AsyncTaskRetro
extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try(Realm r = Realm.getDefaultInstance()) {
Response<Place> response = PlacesAPI.Factory.getInstance().getPlaces().execute();
Place place = response.body();
List<Post> posts = place.getPosts();
r.executeTransaction((realm) -> {
for(Post post : posts) {
RowModel rowModel = new RowModel(post.getNazwa(),
Double.parseDouble(post.getSzer()),
Double.parseDouble(post.getDlug()));
rowModels.add(rowModel);
}
String oldName;
oldName = rowModels.get(0).getName();
shopsNames.add(rowModels.get(0).getName());
RowModel rowModelRealm = realm.createObject(RowModel.class);
for(RowModel rowModel : rowModels) {
rowModelRealm.setName(rowModel.getName());
rowModelRealm.setLattitude(rowModel.getLattitude());
rowModelRealm.setLongitude(rowModel.getLongitude());
if(rowModel.getName().equals(oldName)) {
continue;
}
oldName = rowModel.getName();
shopsNames.add(rowModel.getName());
}
});
// no need to manually sort if you use RealmBaseAdapter with findAllSorted()
}
return null;
}
}
Upvotes: 1
Reputation: 108
a Realm object has the method:
insert(Iterable<E> objects)
which should let you copy all of your RowModel
objects in at once
Upvotes: 1