Optimize realm transactions

This commit is contained in:
Phillip Thelen 2017-09-12 16:37:17 +02:00
parent e712b9a6a2
commit 7261d88103
15 changed files with 110 additions and 94 deletions

View file

@ -74,6 +74,9 @@
-dontwarn javax.**
-dontwarn io.realm.**
#support library
-keep class android.support.v7.widget.SearchView { *; }
#eventbus
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;

View file

@ -102,7 +102,7 @@
android:layout_height="0dp"
android:layout_weight="1" />
<com.habitrpg.android.habitica.ui.views.CurrencyView
<com.habitrpg.android.habitica.ui.views.CurrencyViews
android:id="@+id/currencyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

View file

@ -124,7 +124,7 @@ public class ChallengeRepositoryImpl extends BaseRepositoryImpl<ChallengeLocalRe
@Override
public Observable<List<Challenge>> retrieveChallenges(User user) {
return apiClient.getUserChallenges()
.doOnNext(challenges -> localRepository.saveChallenges(user, challenges));
.doOnNext(localRepository::save);
}
@Override

View file

@ -267,7 +267,7 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl<InventoryLoca
@Override
public Observable<BuyResponse> buyItem(User user, String key, double value) {
return apiClient.buyItem(key)
.doOnNext(buyResponse -> localRepository.executeTransaction(realm -> {
.doOnNext(buyResponse -> {
User copiedUser = localRepository.getUnmanagedCopy(user);
if (buyResponse.items != null) {
buyResponse.items.setUserId(user.getId());
@ -291,7 +291,7 @@ public class InventoryRepositoryImpl extends ContentRepositoryImpl<InventoryLoca
copiedUser.getStats().setLvl(buyResponse.lvl);
}
localRepository.save(copiedUser);
}));
});
}
@Override

View file

@ -28,6 +28,8 @@ import io.realm.RealmList;
import io.realm.RealmResults;
import rx.Observable;
import static com.habitrpg.android.habitica.R.id.item;
public class TaskRepositoryImpl extends BaseRepositoryImpl<TaskLocalRepository> implements TaskRepository {
@ -116,13 +118,18 @@ public class TaskRepositoryImpl extends BaseRepositoryImpl<TaskLocalRepository>
public Observable<Task> scoreChecklistItem(String taskId, String itemId) {
return apiClient.scoreChecklistItem(taskId, itemId)
.flatMap(task -> localRepository.getTask(taskId).first())
.doOnNext(task -> localRepository.executeTransaction(realm -> {
.doOnNext(task -> {
ChecklistItem updatedItem = null;
for (ChecklistItem item : task.getChecklist()) {
if (itemId.equals(item.getId())) {
item.setCompleted(!item.getCompleted());
updatedItem = item;
}
}
}));
if (updatedItem != null) {
ChecklistItem finalUpdatedItem = updatedItem;
localRepository.executeTransaction(realm -> finalUpdatedItem.setCompleted(!finalUpdatedItem.getCompleted()));
}
});
}
@Override

View file

@ -19,7 +19,5 @@ public interface ChallengeLocalRepository extends BaseLocalRepository {
Observable<RealmResults<Challenge>> getUserChallenges(String userId);
void saveChallenges(User user, List<Challenge> challenges);
void setParticipating(Challenge challenge, boolean isParticipating);
}

View file

@ -53,11 +53,6 @@ public class RealmChallengeLocalRepository extends RealmBaseLocalRepository impl
.filter(RealmResults::isLoaded);
}
@Override
public void saveChallenges(User user, List<Challenge> challenges) {
realm.executeTransactionAsync(realm1 -> realm1.insertOrUpdate(challenges));
}
@Override
public void setParticipating(Challenge challenge, boolean isParticipating) {
realm.executeTransaction(realm1 -> challenge.isParticipating = isParticipating);

View file

@ -97,18 +97,18 @@ public class RealmSocialLocalRepository extends RealmBaseLocalRepository impleme
if (chatMessage.userLikesMessage(userId) == liked) {
return;
}
realm.executeTransaction(realm1 -> {
if (liked) {
if (liked) {
realm.executeTransaction(realm1 -> {
chatMessage.likes.add(new ChatMessageLike(userId));
} else {
for (ChatMessageLike like : chatMessage.likes) {
if (userId.equals(like.id)) {
like.deleteFromRealm();
return;
}
});
} else {
for (ChatMessageLike like : chatMessage.likes) {
if (userId.equals(like.id)) {
realm.executeTransaction(realm1 -> like.deleteFromRealm());
return;
}
}
});
}
}
@Override

View file

@ -45,41 +45,37 @@ public class RealmTaskLocalRepository extends RealmBaseLocalRepository implement
@Override
public void saveTasks(@Nullable String userId, TasksOrder tasksOrder, TaskList tasks) {
realm.executeTransactionAsync(realm1 -> {
List<Task> sortedTasks = new ArrayList<>();
if (tasks != null) {
if (tasksOrder != null) {
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getHabits()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getDailys()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getTodos()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getRewards()));
} else {
sortedTasks.addAll(tasks.tasks.values());
}
}
if (userId != null) {
removeOldTasks(userId, sortedTasks);
List<Task> sortedTasks = new ArrayList<>();
if (tasks != null) {
if (tasksOrder != null) {
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getHabits()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getDailys()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getTodos()));
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.getRewards()));
} else {
sortedTasks.addAll(tasks.tasks.values());
List<ChecklistItem> allChecklistItems = new ArrayList<>();
for (Task t : sortedTasks) {
if (t.checklist != null) {
allChecklistItems.addAll(t.checklist);
}
}
if (userId != null) {
removeOldTasks(realm1, userId, sortedTasks);
removeOldChecklists(allChecklistItems);
List<ChecklistItem> allChecklistItems = new ArrayList<>();
for (Task t : sortedTasks) {
if (t.checklist != null) {
allChecklistItems.addAll(t.checklist);
}
List<RemindersItem> allReminders = new ArrayList<>();
for (Task t : sortedTasks) {
if (t.getReminders() != null) {
allReminders.addAll(t.getReminders());
}
removeOldChecklists(realm1, allChecklistItems);
List<RemindersItem> allReminders = new ArrayList<>();
for (Task t : sortedTasks) {
if (t.getReminders() != null) {
allReminders.addAll(t.getReminders());
}
}
removeOldReminders(realm1, allReminders);
}
realm1.insertOrUpdate(sortedTasks);
});
removeOldReminders(allReminders);
}
realm.executeTransactionAsync(realm1 -> realm1.insertOrUpdate(sortedTasks));
}
private List<Task> sortTasks(Map<String, Task> taskMap, List<String> taskOrder) {
@ -102,10 +98,16 @@ public class RealmTaskLocalRepository extends RealmBaseLocalRepository implement
realm.executeTransaction(realm1 -> realm1.insertOrUpdate(task));
}
private void removeOldTasks(Realm realm, String userID, List<Task> onlineTaskList) {
private void removeOldTasks(String userID, List<Task> onlineTaskList) {
OrderedRealmCollectionSnapshot<Task> localTasks = realm.where(Task.class).equalTo("userId", userID).findAll().createSnapshot();
List<Task> tasksToDelete = new ArrayList<>();
for (Task localTask : localTasks) {
if (!onlineTaskList.contains(localTask)) {
tasksToDelete.add(localTask);
}
}
realm.executeTransaction(realm1 -> {
for (Task localTask : tasksToDelete) {
if (localTask.checklist != null) {
localTask.checklist.deleteAllFromRealm();
}
@ -114,25 +116,37 @@ public class RealmTaskLocalRepository extends RealmBaseLocalRepository implement
}
localTask.deleteFromRealm();
}
}
});
}
private void removeOldChecklists(Realm realm, List<ChecklistItem> onlineItems) {
private void removeOldChecklists(List<ChecklistItem> onlineItems) {
OrderedRealmCollectionSnapshot<ChecklistItem> localItems = realm.where(ChecklistItem.class).findAll().createSnapshot();
List<ChecklistItem> itemsToDelete = new ArrayList<>();
for (ChecklistItem localItem : localItems) {
if (!onlineItems.contains(localItem)) {
localItem.deleteFromRealm();
itemsToDelete.add(localItem);
}
}
realm.executeTransaction(realm1 -> {
for (ChecklistItem item : itemsToDelete) {
item.deleteFromRealm();
}
});
}
private void removeOldReminders(Realm realm, List<RemindersItem> onlineReminders) {
private void removeOldReminders(List<RemindersItem> onlineReminders) {
OrderedRealmCollectionSnapshot<RemindersItem> localReminders = realm.where(RemindersItem.class).findAll().createSnapshot();
List<RemindersItem> itemsToDelete = new ArrayList<>();
for (RemindersItem localItem : localReminders) {
if (!onlineReminders.contains(localItem)) {
localItem.deleteFromRealm();
itemsToDelete.add(localItem);
}
}
realm.executeTransaction(realm1 -> {
for (RemindersItem item : itemsToDelete) {
item.deleteFromRealm();
}
});
}
@Override
public void deleteTask(String taskID) {

View file

@ -35,23 +35,26 @@ public class RealmUserLocalRepository extends RealmBaseLocalRepository implement
@Override
public void saveUser(User user) {
realm.executeTransaction(realm1 -> {
realm1.insertOrUpdate(user);
if (user.getTags() != null) {
removeOldTags(user.getId(), user.getTags());
}
});
realm.executeTransaction(realm1 -> realm1.insertOrUpdate(user));
if (user.getTags() != null) {
removeOldTags(user.getId(), user.getTags());
}
}
private void removeOldTags(String userId, List<Tag> onlineTags) {
OrderedRealmCollectionSnapshot<Tag> tags = realm.where(Tag.class).equalTo("userId", userId).findAll().createSnapshot();
List<Tag> tagsToDelete = new ArrayList<>();
for (Tag tag : tags) {
if (!onlineTags.contains(tag)) {
tag.deleteFromRealm();
tagsToDelete.add(tag);
}
}
realm.executeTransaction(realm1 -> {
for (Tag tag : tagsToDelete) {
tag.deleteFromRealm();
}
});
}
@Override

View file

@ -16,23 +16,23 @@ public class Inbox extends RealmObject {
private String userId;
User user;
private Boolean optOut;
private boolean optOut;
private RealmList<ChatMessage> messages;
@Ignore
private List<Object> blocks = new ArrayList<>();
private Integer newMessages;
private int newMessages;
/**
* @return The optOut
*/
public Boolean getOptOut() {
public boolean getOptOut() {
return optOut;
}
/**
* @param optOut The optOut
*/
public void setOptOut(Boolean optOut) {
public void setOptOut(boolean optOut) {
this.optOut = optOut;
}
@ -67,14 +67,14 @@ public class Inbox extends RealmObject {
/**
* @return The newMessages
*/
public Integer getNewMessages() {
public int getNewMessages() {
return newMessages;
}
/**
* @param newMessages The newMessages
*/
public void setNewMessages(Integer newMessages) {
public void setNewMessages(int newMessages) {
this.newMessages = newMessages;
}

View file

@ -17,8 +17,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.habitrpg.android.habitica.R;
@ -88,9 +86,6 @@ public class ChallengeDetailActivity extends BaseActivity {
@BindView(R.id.floating_menu_wrapper)
FrameLayout floatingMenuWrapper;
@BindView(R.id.gem_icon)
ImageView gemIconView;
// region UseCases
@Inject
@ -245,8 +240,6 @@ public class ChallengeDetailActivity extends BaseActivity {
challengeViewHolder.bind(challenge);
});
}
gemIconView.setImageBitmap(HabiticaIconsHelper.imageOfGem_36());
}
private void createTaskRecyclerFragment(ObservableList<Task> fullList) {

View file

@ -394,7 +394,7 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria
}
private void displayNewInboxMessagesBadge() {
Integer numberOfUnreadPms = this.user.getInbox().getNewMessages();
int numberOfUnreadPms = this.user.getInbox().getNewMessages();
IDrawerItem newInboxItem;
if (numberOfUnreadPms <= 0) {

View file

@ -98,16 +98,6 @@ public abstract class BaseMainFragment extends BaseFragment {
}
}
if (tabLayout != null) {
if (this.usesTabLayout) {
tabLayout.removeAllTabs();
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
tabLayout.setVisibility(View.GONE);
}
}
if (bottomNavigation != null) {
if (this.usesBottomNavigation) {
bottomNavigation.removeOnTabSelectListener();
@ -128,9 +118,23 @@ public abstract class BaseMainFragment extends BaseFragment {
activity.setActiveFragment(this);
}
updateTabLayoutVisibility();
return null;
}
private void updateTabLayoutVisibility() {
if (tabLayout != null) {
if (this.usesTabLayout) {
tabLayout.removeAllTabs();
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
tabLayout.setVisibility(View.GONE);
}
}
}
@Override
public void onDestroy() {
if (userRepository != null) {

View file

@ -7,6 +7,7 @@ import android.widget.TextView;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.events.TaskTappedEvent;
import com.habitrpg.android.habitica.events.commands.BuyRewardCommand;
import com.habitrpg.android.habitica.helpers.NumberAbbreviator;
import com.habitrpg.android.habitica.models.tasks.Task;
import com.habitrpg.android.habitica.ui.ItemDetailDialog;
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper;
@ -40,7 +41,7 @@ public class RewardViewHolder extends BaseTaskViewHolder {
public void bindHolder(Task newTask, int position) {
super.bindHolder(newTask, position);
this.priceLabel.setText(this.priceFormat.format(this.task.value));
this.priceLabel.setText(NumberAbbreviator.abbreviate(itemView.getContext(), this.task.value));
}
private boolean isItem() {
@ -68,9 +69,7 @@ public class RewardViewHolder extends BaseTaskViewHolder {
dialog.setImage("shop_" + this.task.getId());
dialog.setCurrency("gold");
dialog.setValue(task.getValue());
dialog.setBuyListener((clickedDialog, which) -> {
this.buyReward();
});
dialog.setBuyListener((clickedDialog, which) -> this.buyReward());
dialog.show();
} else {
TaskTappedEvent event = new TaskTappedEvent();