Fix losing widget state on restart
This commit is contained in:
parent
4a8c0b7a2d
commit
ea21bbe811
@ -26,7 +26,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.ContextMenu;
|
||||
import jscl.math.Generic;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
@ -34,6 +34,8 @@ import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import jscl.math.Generic;
|
||||
|
||||
public class DisplayState implements Parcelable, ContextMenu.ContextMenuInfo {
|
||||
|
||||
public static final Creator<DisplayState> CREATOR = new Creator<DisplayState>() {
|
||||
@ -143,4 +145,8 @@ public class DisplayState implements Parcelable, ContextMenu.ContextMenuInfo {
|
||||
dest.writeString(text);
|
||||
dest.writeByte((byte) (valid ? 1 : 0));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return valid && TextUtils.isEmpty(text);
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Vibrator;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.solovyev.android.calculator.buttons.CppButton;
|
||||
import org.solovyev.android.calculator.history.History;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
@ -19,6 +22,8 @@ public final class WidgetReceiver extends BroadcastReceiver {
|
||||
|
||||
@Inject
|
||||
Keyboard keyboard;
|
||||
@Inject
|
||||
History history;
|
||||
|
||||
@Nonnull
|
||||
public static Intent newButtonClickedIntent(@Nonnull Context context, @Nonnull CppButton button) {
|
||||
@ -43,9 +48,21 @@ public final class WidgetReceiver extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
if (history.isLoaded()) {
|
||||
if (!keyboard.buttonPressed(button.action)) {
|
||||
// prevent vibrate
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// if app has been killed we need first to restore the state and only after doing this
|
||||
// to apply actions. Otherwise, we will apply actions on the empty editor
|
||||
history.runWhenLoaded(new MyRunnable(keyboard, button.action));
|
||||
}
|
||||
|
||||
vibrate(context);
|
||||
}
|
||||
|
||||
private void vibrate(@NonNull Context context) {
|
||||
if (!keyboard.isVibrateOnKeypress()) {
|
||||
return;
|
||||
}
|
||||
@ -55,4 +72,21 @@ public final class WidgetReceiver extends BroadcastReceiver {
|
||||
}
|
||||
vibrator.vibrate(10);
|
||||
}
|
||||
|
||||
private static class MyRunnable implements Runnable {
|
||||
@NonNull
|
||||
private final Keyboard keyboard;
|
||||
@NonNull
|
||||
private final String action;
|
||||
|
||||
public MyRunnable(@NonNull Keyboard keyboard, @NonNull String action) {
|
||||
this.keyboard = keyboard;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
keyboard.buttonPressed(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,9 @@ public class History {
|
||||
private final RecentHistory recent = new RecentHistory();
|
||||
@Nonnull
|
||||
private final List<HistoryState> saved = new ArrayList<>();
|
||||
@Nonnull
|
||||
private final List<Runnable> whenLoadedRunnables = new ArrayList<>();
|
||||
private boolean loaded;
|
||||
@Inject
|
||||
Application application;
|
||||
@Inject
|
||||
@ -217,15 +220,32 @@ public class History {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Check.isTrue(recent.isEmpty());
|
||||
Check.isTrue(saved.isEmpty());
|
||||
recent.addInitial(recentStates);
|
||||
saved.addAll(savedStates);
|
||||
editor.onHistoryLoaded(recent);
|
||||
onLoaded(recentStates, savedStates);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onLoaded(@NonNull List<HistoryState> recentStates, @NonNull List<HistoryState> savedStates) {
|
||||
Check.isTrue(saved.isEmpty());
|
||||
Check.isMainThread();
|
||||
final boolean wasEmpty = recent.isEmpty();
|
||||
recent.addInitial(recentStates);
|
||||
saved.addAll(savedStates);
|
||||
if (wasEmpty) {
|
||||
// user has typed nothing while we were loading, let's use recent history to restore
|
||||
// editor state
|
||||
editor.onHistoryLoaded(recent);
|
||||
} else {
|
||||
// user has types something => we should schedule save
|
||||
postRecentWrite();
|
||||
}
|
||||
loaded = true;
|
||||
for (Runnable runnable : whenLoadedRunnables) {
|
||||
runnable.run();
|
||||
}
|
||||
whenLoadedRunnables.clear();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private List<HistoryState> tryLoadStates(@NonNull File file) {
|
||||
try {
|
||||
@ -238,6 +258,10 @@ public class History {
|
||||
|
||||
public void addRecent(@Nonnull HistoryState state) {
|
||||
Check.isMainThread();
|
||||
if (recent.isEmpty() && state.isEmpty()) {
|
||||
// don't add empty states to empty history
|
||||
return;
|
||||
}
|
||||
recent.add(state);
|
||||
onRecentChanged(new AddedEvent(state, true));
|
||||
}
|
||||
@ -255,15 +279,23 @@ public class History {
|
||||
}
|
||||
|
||||
private void onRecentChanged(@Nonnull Object event) {
|
||||
handler.removeCallbacks(writeRecent);
|
||||
handler.postDelayed(writeRecent, 5000);
|
||||
postRecentWrite();
|
||||
bus.post(event);
|
||||
}
|
||||
|
||||
private void postRecentWrite() {
|
||||
handler.removeCallbacks(writeRecent);
|
||||
handler.postDelayed(writeRecent, 5000);
|
||||
}
|
||||
|
||||
private void onSavedChanged(@Nonnull Object event) {
|
||||
postSavedWrite();
|
||||
bus.post(event);
|
||||
}
|
||||
|
||||
private void postSavedWrite() {
|
||||
handler.removeCallbacks(writeSaved);
|
||||
handler.postDelayed(writeSaved, 500);
|
||||
bus.post(event);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -359,6 +391,15 @@ public class History {
|
||||
addRecent(HistoryState.builder(editorState, displayState).build());
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public void runWhenLoaded(@NonNull Runnable runnable) {
|
||||
Check.isTrue(!loaded);
|
||||
whenLoadedRunnables.add(runnable);
|
||||
}
|
||||
|
||||
public static class ClearedEvent {
|
||||
public final boolean recent;
|
||||
|
||||
@ -406,6 +447,9 @@ public class History {
|
||||
@Override
|
||||
public void run() {
|
||||
Check.isMainThread();
|
||||
if (!loaded) {
|
||||
return;
|
||||
}
|
||||
// don't need to save intermediate states, thus {@link History#getRecent}
|
||||
final List<HistoryState> states = recent ? getRecent(false) : getSaved();
|
||||
backgroundThread.execute(new Runnable() {
|
||||
|
@ -3,6 +3,7 @@ package org.solovyev.android.calculator.history;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@ -15,8 +16,6 @@ import org.solovyev.android.calculator.json.Jsonable;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
|
||||
public class HistoryState implements Parcelable, Jsonable {
|
||||
|
||||
public static final Creator<HistoryState> CREATOR = new Creator<HistoryState>() {
|
||||
@ -103,7 +102,7 @@ public class HistoryState implements Parcelable, Jsonable {
|
||||
json.put(JSON_EDITOR, editor.toJson());
|
||||
json.put(JSON_DISPLAY, display.toJson());
|
||||
json.put(JSON_TIME, time);
|
||||
if (!isEmpty(comment)) {
|
||||
if (!TextUtils.isEmpty(comment)) {
|
||||
json.put(JSON_COMMENT, comment);
|
||||
}
|
||||
return json;
|
||||
@ -173,6 +172,10 @@ public class HistoryState implements Parcelable, Jsonable {
|
||||
dest.writeString(comment);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return display.isEmpty() && editor.isEmpty() && TextUtils.isEmpty(comment);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
@NonNull
|
||||
|
Loading…
Reference in New Issue
Block a user