Refactor tasks; break progress bars

pull/151/head
Alinson S. Xavier 9 years ago
parent 94a5db2208
commit d54de9df89

@ -60,6 +60,9 @@ public class BaseAndroidTest
@Inject @Inject
protected CommandRunner commandRunner; protected CommandRunner commandRunner;
@Inject
protected TaskRunner taskRunner;
@Inject @Inject
protected HabitLogger logger; protected HabitLogger logger;
@ -139,7 +142,7 @@ public class BaseAndroidTest
return; return;
} }
BaseTask.waitForTasks(10000); taskRunner.waitForTasks(10000);
} }
catch (Exception e) catch (Exception e)
{ {

@ -40,6 +40,7 @@ import static org.hamcrest.core.IsNot.not;
public class ExportCSVTaskTest extends BaseAndroidTest public class ExportCSVTaskTest extends BaseAndroidTest
{ {
@Before @Before
@Override
public void setUp() public void setUp()
{ {
super.setUp(); super.setUp();
@ -48,20 +49,20 @@ public class ExportCSVTaskTest extends BaseAndroidTest
@Test @Test
public void testExportCSV() throws Throwable public void testExportCSV() throws Throwable
{ {
fixtures.purgeHabits(habitList);
fixtures.createShortHabit(); fixtures.createShortHabit();
List<Habit> selected = new LinkedList<>(); List<Habit> selected = new LinkedList<>();
for (Habit h : habitList) selected.add(h); for (Habit h : habitList) selected.add(h);
ExportCSVTask task = new ExportCSVTask(habitList, selected, null); taskRunner.execute(
task.setListener(archiveFilename -> { new ExportCSVTask(habitList, selected, archiveFilename -> {
assertThat(archiveFilename, is(not(nullValue()))); assertThat(archiveFilename, is(not(nullValue())));
File f = new File(archiveFilename); File f = new File(archiveFilename);
assertTrue(f.exists()); assertTrue(f.exists());
assertTrue(f.canRead()); assertTrue(f.canRead());
}); }));
task.execute();
waitForAsyncTasks(); waitForAsyncTasks();
} }
} }

@ -19,20 +19,18 @@
package org.isoron.uhabits.tasks; package org.isoron.uhabits.tasks;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*; import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.BaseAndroidTest; import org.isoron.uhabits.*;
import org.junit.Before; import org.junit.*;
import org.junit.Test; import org.junit.runner.*;
import org.junit.runner.RunWith;
import java.io.File; import java.io.*;
import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsNot.not;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@ -48,21 +46,15 @@ public class ExportDBTaskTest extends BaseAndroidTest
@Test @Test
public void testExportCSV() throws Throwable public void testExportCSV() throws Throwable
{ {
ExportDBTask task = new ExportDBTask(null); ExportDBTask task = new ExportDBTask(filename -> {
task.setListener(new ExportDBTask.Listener()
{
@Override
public void onExportDBFinished(String filename)
{
assertThat(filename, is(not(nullValue()))); assertThat(filename, is(not(nullValue())));
File f = new File(filename); File f = new File(filename);
assertTrue(f.exists()); assertTrue(f.exists());
assertTrue(f.canRead()); assertTrue(f.canRead());
}
}); });
task.execute(); taskRunner.execute(task);
waitForAsyncTasks(); waitForAsyncTasks();
} }
} }

@ -19,23 +19,18 @@
package org.isoron.uhabits.tasks; package org.isoron.uhabits.tasks;
import android.support.annotation.NonNull; import android.support.test.runner.*;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.*; import android.test.suitebuilder.annotation.*;
import org.isoron.uhabits.BaseAndroidTest; import org.isoron.uhabits.*;
import org.isoron.uhabits.utils.FileUtils; import org.isoron.uhabits.utils.*;
import org.junit.Before; import org.junit.*;
import org.junit.Test; import org.junit.runner.*;
import org.junit.runner.RunWith;
import java.io.File; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.*;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@MediumTest @MediumTest
@ -52,46 +47,33 @@ public class ImportDataTaskTest extends BaseAndroidTest
if (baseDir == null) fail("baseDir should not be null"); if (baseDir == null) fail("baseDir should not be null");
} }
private void copyAssetToFile(String assetPath, File dst) throws IOException @Test
public void testImportInvalidData() throws Throwable
{ {
InputStream in = testContext.getAssets().open(assetPath); assertTaskResult(ImportDataTask.NOT_RECOGNIZED, "icon.png");
FileUtils.copy(in, dst);
} }
private void assertTaskResult(final int expectedResult, String assetFilename) throws Throwable @Test
{ public void testImportValidData() throws Throwable
ImportDataTask task = createTask(assetFilename);
task.setListener(new ImportDataTask.Listener()
{
@Override
public void onImportDataFinished(int result)
{ {
assertThat(result, equalTo(expectedResult)); assertTaskResult(ImportDataTask.SUCCESS, "loop.db");
}
});
task.execute();
waitForAsyncTasks();
} }
@NonNull private void assertTaskResult(final int expectedResult,
private ImportDataTask createTask(String assetFilename) throws IOException String assetFilename) throws Throwable
{ {
File file = new File(String.format("%s/%s", baseDir.getPath(), assetFilename)); File file = new File(baseDir.getPath() + "/" + assetFilename);
copyAssetToFile(assetFilename, file); copyAssetToFile(assetFilename, file);
return new ImportDataTask(habitList, file, null);
}
@Test taskRunner.execute(new ImportDataTask(habitList, file,
public void testImportInvalidData() throws Throwable (result) -> assertThat(result, equalTo(expectedResult))));
{
assertTaskResult(ImportDataTask.NOT_RECOGNIZED, "icon.png"); waitForAsyncTasks();
} }
@Test private void copyAssetToFile(String assetPath, File dst) throws IOException
public void testImportValidData() throws Throwable
{ {
assertTaskResult(ImportDataTask.SUCCESS, "loop.db"); InputStream in = testContext.getAssets().open(assetPath);
FileUtils.copy(in, dst);
} }
} }

@ -42,18 +42,22 @@ import org.isoron.uhabits.widgets.*;
*/ */
public interface BaseComponent public interface BaseComponent
{ {
CommandRunner getCommandRunner();
HabitList getHabitList();
IntentFactory getIntentFactory(); IntentFactory getIntentFactory();
ReminderScheduler getReminderScheduler();
TaskRunner getTaskRunner();
void inject(CheckmarkButtonController checkmarkButtonController); void inject(CheckmarkButtonController checkmarkButtonController);
void inject(ListHabitsController listHabitsController); void inject(ListHabitsController listHabitsController);
void inject(CheckmarkPanelView checkmarkPanelView); void inject(CheckmarkPanelView checkmarkPanelView);
void inject(ToggleRepetitionTask toggleRepetitionTask);
void inject(HabitCardListCache habitCardListCache);
void inject(WidgetReceiver widgetReceiver); void inject(WidgetReceiver widgetReceiver);
void inject(ListHabitsSelectionMenu listHabitsSelectionMenu); void inject(ListHabitsSelectionMenu listHabitsSelectionMenu);
@ -84,8 +88,6 @@ public interface BaseComponent
void inject(BaseSystem baseSystem); void inject(BaseSystem baseSystem);
void inject(HistoryEditorDialog historyEditorDialog);
void inject(HabitsApplication application); void inject(HabitsApplication application);
void inject(Habit habit); void inject(Habit habit);
@ -110,8 +112,6 @@ public interface BaseComponent
void inject(ReceiverActions receiverActions); void inject(ReceiverActions receiverActions);
void inject(ReminderReceiver reminderReceiver);
void inject(ReminderScheduler reminderScheduler); void inject(ReminderScheduler reminderScheduler);
void inject(ListHabitsScreen listHabitsScreen); void inject(ListHabitsScreen listHabitsScreen);

@ -19,12 +19,12 @@
package org.isoron.uhabits.commands; package org.isoron.uhabits.commands;
import android.support.annotation.NonNull; import android.support.annotation.*;
import android.support.annotation.Nullable;
import org.isoron.uhabits.tasks.BaseTask; import org.isoron.uhabits.*;
import org.isoron.uhabits.tasks.*;
import java.util.LinkedList; import java.util.*;
import javax.inject.*; import javax.inject.*;
@ -37,19 +37,17 @@ import javax.inject.*;
@Singleton @Singleton
public class CommandRunner public class CommandRunner
{ {
private TaskRunner taskRunner;
private LinkedList<Listener> listeners; private LinkedList<Listener> listeners;
@Inject @Inject
public CommandRunner() public CommandRunner()
{ {
taskRunner = HabitsApplication.getComponent().getTaskRunner();
listeners = new LinkedList<>(); listeners = new LinkedList<>();
} }
private static CommandRunner getInstance()
{
return null;
}
public void addListener(Listener l) public void addListener(Listener l)
{ {
listeners.add(l); listeners.add(l);
@ -57,23 +55,21 @@ public class CommandRunner
public void execute(final Command command, final Long refreshKey) public void execute(final Command command, final Long refreshKey)
{ {
new BaseTask() taskRunner.execute(new Task()
{ {
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
command.execute(); command.execute();
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
for (Listener l : listeners) for (Listener l : listeners)
l.onCommandExecuted(command, refreshKey); l.onCommandExecuted(command, refreshKey);
super.onPostExecute(null);
} }
}.execute(); });
} }
public void removeListener(Listener l) public void removeListener(Listener l)

@ -46,7 +46,10 @@ public class PebbleReceiver extends PebbleDataReceiver
protected HabitList allHabits; protected HabitList allHabits;
@Inject @Inject
protected CommandRunner runner; protected CommandRunner commandRunner;
@Inject
protected TaskRunner taskRunner;
protected HabitList filteredHabits; protected HabitList filteredHabits;
@ -74,7 +77,7 @@ public class PebbleReceiver extends PebbleDataReceiver
PebbleKit.sendAckToPebble(context, transactionId); PebbleKit.sendAckToPebble(context, transactionId);
Log.d("PebbleReceiver", "<-- " + data.getString(0)); Log.d("PebbleReceiver", "<-- " + data.getString(0));
new SimpleTask(() -> { taskRunner.execute(() -> {
switch (data.getString(0)) switch (data.getString(0))
{ {
case "COUNT": case "COUNT":
@ -89,7 +92,7 @@ public class PebbleReceiver extends PebbleDataReceiver
processToggle(data); processToggle(data);
break; break;
} }
}).execute(); });
} }
private void processFetch(@NonNull PebbleDictionary dict) private void processFetch(@NonNull PebbleDictionary dict)
@ -113,7 +116,8 @@ public class PebbleReceiver extends PebbleDataReceiver
if (habit == null) return; if (habit == null) return;
long today = DateUtils.getStartOfToday(); long today = DateUtils.getStartOfToday();
runner.execute(new ToggleRepetitionCommand(habit, today), habitId); commandRunner.execute(new ToggleRepetitionCommand(habit, today),
habitId);
sendOK(); sendOK();
} }

@ -24,7 +24,6 @@ import android.support.annotation.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import javax.inject.*; import javax.inject.*;
@ -54,9 +53,7 @@ public class ReceiverActions
public void toggle_repetition(@NonNull Habit habit, long timestamp) public void toggle_repetition(@NonNull Habit habit, long timestamp)
{ {
new SimpleTask(() -> { commandRunner.execute(
commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), new ToggleRepetitionCommand(habit, timestamp), habit.getId());
habit.getId());
}).execute();
} }
} }

@ -36,8 +36,6 @@ import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
import javax.inject.*;
/** /**
* The Android BroadcastReceiver for Loop Habit Tracker. * The Android BroadcastReceiver for Loop Habit Tracker.
* <p> * <p>
@ -56,16 +54,20 @@ public class ReminderReceiver extends BroadcastReceiver
private static final String TAG = "ReminderReceiver"; private static final String TAG = "ReminderReceiver";
@Inject private final HabitList habits;
HabitList habits;
private final TaskRunner taskRunner;
@Inject private final ReminderScheduler reminderScheduler;
ReminderScheduler reminderScheduler;
public ReminderReceiver() public ReminderReceiver()
{ {
super(); super();
HabitsApplication.getComponent().inject(this);
BaseComponent component = HabitsApplication.getComponent();
habits = component.getHabitList();
taskRunner = component.getTaskRunner();
reminderScheduler = component.getReminderScheduler();
} }
@Override @Override
@ -115,25 +117,25 @@ public class ReminderReceiver extends BroadcastReceiver
{ {
final Uri data = intent.getData(); final Uri data = intent.getData();
final Habit habit = habits.getById(ContentUris.parseId(data)); final Habit habit = habits.getById(ContentUris.parseId(data));
final Long timestamp = intent.getLongExtra("timestamp", final Long timestamp =
DateUtils.getStartOfToday()); intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
final Long reminderTime = intent.getLongExtra("reminderTime", final Long reminderTime =
DateUtils.getStartOfToday()); intent.getLongExtra("reminderTime", DateUtils.getStartOfToday());
if (habit == null) return; if (habit == null) return;
new BaseTask() taskRunner.execute(new Task()
{ {
int todayValue; int todayValue;
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
todayValue = habit.getCheckmarks().getTodayValue(); todayValue = habit.getCheckmarks().getTodayValue();
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
if (todayValue != Checkmark.UNCHECKED) return; if (todayValue != Checkmark.UNCHECKED) return;
if (!shouldShowReminderToday(intent, habit)) return; if (!shouldShowReminderToday(intent, habit)) return;
@ -141,15 +143,16 @@ public class ReminderReceiver extends BroadcastReceiver
Intent contentIntent = new Intent(context, MainActivity.class); Intent contentIntent = new Intent(context, MainActivity.class);
contentIntent.setData(data); contentIntent.setData(data);
PendingIntent contentPendingIntent = PendingIntent.getActivity( PendingIntent contentPendingIntent =
context, 0, contentIntent, PendingIntent.getActivity(context, 0, contentIntent,
PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntentFactory PendingIntentFactory pendingIntentFactory =
pendingIntentFactory = new PendingIntentFactory(context); new PendingIntentFactory(context);
PendingIntent dismissPendingIntent; PendingIntent dismissPendingIntent;
dismissPendingIntent = pendingIntentFactory.dismissNotification(); dismissPendingIntent =
pendingIntentFactory.dismissNotification();
PendingIntent checkIntentPending = PendingIntent checkIntentPending =
pendingIntentFactory.addCheckmark(habit, timestamp); pendingIntentFactory.addCheckmark(habit, timestamp);
PendingIntent snoozeIntentPending = PendingIntent snoozeIntentPending =
@ -159,12 +162,11 @@ public class ReminderReceiver extends BroadcastReceiver
NotificationCompat.WearableExtender wearableExtender = NotificationCompat.WearableExtender wearableExtender =
new NotificationCompat.WearableExtender().setBackground( new NotificationCompat.WearableExtender().setBackground(
BitmapFactory.decodeResource( BitmapFactory.decodeResource(context.getResources(),
context.getResources(),
R.drawable.stripe)); R.drawable.stripe));
Notification notification = new NotificationCompat.Builder( Notification notification =
context) new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setContentTitle(habit.getName()) .setContentTitle(habit.getName())
.setContentText(habit.getDescription()) .setContentText(habit.getDescription())
@ -190,10 +192,8 @@ public class ReminderReceiver extends BroadcastReceiver
int notificationId = (int) (habit.getId() % Integer.MAX_VALUE); int notificationId = (int) (habit.getId() % Integer.MAX_VALUE);
notificationManager.notify(notificationId, notification); notificationManager.notify(notificationId, notification);
super.onPostExecute(aVoid);
} }
}.execute(); });
} }
private void createReminderAlarmsDelayed() private void createReminderAlarmsDelayed()
@ -216,10 +216,10 @@ public class ReminderReceiver extends BroadcastReceiver
private void onActionSnoozeReminder(Context context, Intent intent) private void onActionSnoozeReminder(Context context, Intent intent)
{ {
Uri data = intent.getData(); Uri data = intent.getData();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( SharedPreferences prefs =
context); PreferenceManager.getDefaultSharedPreferences(context);
long delayMinutes = Long.parseLong( long delayMinutes =
prefs.getString("pref_snooze_interval", "15")); Long.parseLong(prefs.getString("pref_snooze_interval", "15"));
long habitId = ContentUris.parseId(data); long habitId = ContentUris.parseId(data);
Habit habit = habits.getById(habitId); Habit habit = habits.getById(habitId);
@ -238,11 +238,11 @@ public class ReminderReceiver extends BroadcastReceiver
if (!habit.hasReminder()) return false; if (!habit.hasReminder()) return false;
Reminder reminder = habit.getReminder(); Reminder reminder = habit.getReminder();
Long timestamp = intent.getLongExtra("timestamp", Long timestamp =
DateUtils.getStartOfToday()); intent.getLongExtra("timestamp", DateUtils.getStartOfToday());
boolean reminderDays[] = DateUtils.unpackWeekdayList( boolean reminderDays[] =
reminder.getDays()); DateUtils.unpackWeekdayList(reminder.getDays());
int weekday = DateUtils.getWeekday(timestamp); int weekday = DateUtils.getWeekday(timestamp);
return reminderDays[weekday]; return reminderDays[weekday];

@ -1,75 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.*;
import java.util.concurrent.TimeoutException;
public abstract class BaseTask extends AsyncTask<Void, Integer, Void>
{
private static int activeTaskCount;
@CallSuper
@Override
protected void onPreExecute()
{
super.onPreExecute();
activeTaskCount++;
}
@CallSuper
@Override
protected void onPostExecute(Void aVoid)
{
activeTaskCount--;
super.onPostExecute(null);
}
@Override
protected final Void doInBackground(Void... params)
{
doInBackground();
return null;
}
protected abstract void doInBackground();
public static void waitForTasks(long timeout)
throws TimeoutException, InterruptedException
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
throw new UnsupportedOperationException("waitForTasks requires API 16+");
int poolInterval = 100;
while(timeout > 0)
{
if(activeTaskCount == 0) return;
timeout -= poolInterval;
Thread.sleep(poolInterval);
}
throw new TimeoutException();
}
}

@ -28,43 +28,38 @@ import org.isoron.uhabits.utils.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
public class ExportCSVTask extends BaseTask public class ExportCSVTask implements Task
{ {
private ProgressBar progressBar; private String archiveFilename;
@NonNull
private final List<Habit> selectedHabits; private final List<Habit> selectedHabits;
private String archiveFilename; @NonNull
private final ExportCSVTask.Listener listener;
private ExportCSVTask.Listener listener;
@NonNull @NonNull
private final HabitList habitList; private final HabitList habitList;
public ExportCSVTask(HabitList habitList, public ExportCSVTask(@NonNull HabitList habitList,
List<Habit> selectedHabits, @NonNull List<Habit> selectedHabits,
ProgressBar progressBar) @NonNull Listener listener)
{ {
this.listener = listener;
this.habitList = habitList; this.habitList = habitList;
this.selectedHabits = selectedHabits; this.selectedHabits = selectedHabits;
this.progressBar = progressBar;
}
public void setListener(Listener listener)
{
this.listener = listener;
} }
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
try try
{ {
File dir = FileUtils.getFilesDir("CSV"); File dir = FileUtils.getFilesDir("CSV");
if (dir == null) return; if (dir == null) return;
HabitsCSVExporter exporter = HabitsCSVExporter exporter;
new HabitsCSVExporter(habitList, selectedHabits, dir); exporter = new HabitsCSVExporter(habitList, selectedHabits, dir);
archiveFilename = exporter.writeArchive(); archiveFilename = exporter.writeArchive();
} }
catch (IOException e) catch (IOException e)
@ -74,19 +69,9 @@ public class ExportCSVTask extends BaseTask
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{
if (listener != null) listener.onExportCSVFinished(archiveFilename);
if (progressBar != null) progressBar.hide();
super.onPostExecute(null);
}
@Override
protected void onPreExecute()
{ {
super.onPreExecute(); listener.onExportCSVFinished(archiveFilename);
if (progressBar != null) progressBar.show();
} }
public interface Listener public interface Listener

@ -19,52 +19,26 @@
package org.isoron.uhabits.tasks; package org.isoron.uhabits.tasks;
import android.support.annotation.Nullable; import android.support.annotation.*;
import org.isoron.uhabits.utils.DatabaseUtils; import org.isoron.uhabits.utils.*;
import org.isoron.uhabits.utils.FileUtils;
import java.io.File; import java.io.*;
import java.io.IOException;
public class ExportDBTask extends BaseTask public class ExportDBTask implements Task
{ {
public interface Listener
{
void onExportDBFinished(@Nullable String filename);
}
private ProgressBar progressBar;
private String filename; private String filename;
private Listener listener;
public ExportDBTask(ProgressBar progressBar) @NonNull
{ private final Listener listener;
this.progressBar = progressBar;
}
public void setListener(Listener listener) public ExportDBTask(@NonNull Listener listener)
{ {
this.listener = listener; this.listener = listener;
} }
@Override @Override
protected void onPreExecute() public void doInBackground()
{
super.onPreExecute();
if(progressBar != null) progressBar.show();
}
@Override
protected void onPostExecute(Void aVoid)
{
if(listener != null) listener.onExportDBFinished(filename);
if(progressBar != null) progressBar.hide();
super.onPostExecute(null);
}
@Override
protected void doInBackground()
{ {
filename = null; filename = null;
@ -80,4 +54,15 @@ public class ExportDBTask extends BaseTask
e.printStackTrace(); e.printStackTrace();
} }
} }
@Override
public void onPostExecute()
{
listener.onExportDBFinished(filename);
}
public interface Listener
{
void onExportDBFinished(@Nullable String filename);
}
} }

@ -26,7 +26,7 @@ import org.isoron.uhabits.models.*;
import java.io.*; import java.io.*;
public class ImportDataTask extends BaseTask public class ImportDataTask implements Task
{ {
public static final int FAILED = 3; public static final int FAILED = 3;
@ -34,36 +34,28 @@ public class ImportDataTask extends BaseTask
public static final int SUCCESS = 1; public static final int SUCCESS = 1;
@Nullable int result;
private final ProgressBar progressBar;
@NonNull @NonNull
private final File file; private final File file;
@Nullable @NonNull
private Listener listener; private final Listener listener;
int result;
@NonNull @NonNull
private HabitList habits; private final HabitList habits;
public ImportDataTask(@NonNull HabitList habits, public ImportDataTask(@NonNull HabitList habits,
@NonNull File file, @NonNull File file,
@Nullable ProgressBar progressBar) @NonNull Listener listener)
{ {
this.listener = listener;
this.habits = habits; this.habits = habits;
this.file = file; this.file = file;
this.progressBar = progressBar;
}
public void setListener(@Nullable Listener listener)
{
this.listener = listener;
} }
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
try try
{ {
@ -86,19 +78,9 @@ public class ImportDataTask extends BaseTask
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
if (progressBar != null) progressBar.hide(); listener.onImportDataFinished(result);
if (listener != null) listener.onImportDataFinished(result);
super.onPostExecute(null);
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
if (progressBar != null) progressBar.show();
} }
public interface Listener public interface Listener

@ -19,24 +19,19 @@
package org.isoron.uhabits.tasks; package org.isoron.uhabits.tasks;
public class SimpleTask import android.support.annotation.*;
{
private final BaseTask baseTask;
public SimpleTask(Runnable runnable) public interface Task
{
this.baseTask = new BaseTask()
{
@Override
protected void doInBackground()
{ {
runnable.run(); default void cancel() {}
}
};
}
public void execute() void doInBackground();
{
baseTask.execute(); default void onAttached(@NonNull TaskRunner runner) {}
}
default void onPostExecute() {}
default void onPreExecute() {}
default void onProgressUpdate(int value) {}
} }

@ -0,0 +1,117 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
import android.os.*;
import java.util.*;
import java.util.concurrent.*;
import javax.inject.*;
@Singleton
public class TaskRunner
{
private final LinkedList<CustomAsyncTask> activeTasks;
@Inject
public TaskRunner()
{
activeTasks = new LinkedList<>();
}
public void execute(Task task)
{
task.onAttached(this);
new CustomAsyncTask(task).execute();
}
public void setCurrentProgress(Task task, int progress)
{
for (CustomAsyncTask asyncTask : activeTasks)
if (asyncTask.getTask() == task) asyncTask.publish(progress);
}
public void waitForTasks(long timeout)
throws TimeoutException, InterruptedException
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
throw new UnsupportedOperationException("waitForTasks requires API 16+");
int poolInterval = 100;
while(timeout > 0)
{
if(activeTasks.isEmpty()) return;
timeout -= poolInterval;
Thread.sleep(poolInterval);
}
throw new TimeoutException();
}
private class CustomAsyncTask extends AsyncTask<Void, Integer, Void>
{
private final Task task;
public CustomAsyncTask(Task task)
{
this.task = task;
}
public Task getTask()
{
return task;
}
public void publish(int progress)
{
publishProgress(progress);
}
@Override
protected Void doInBackground(Void... params)
{
task.doInBackground();
return null;
}
@Override
protected void onPostExecute(Void aVoid)
{
task.onPostExecute();
activeTasks.remove(this);
}
@Override
protected void onProgressUpdate(Integer... values)
{
task.onProgressUpdate(values[0]);
}
@Override
protected void onPreExecute()
{
activeTasks.add(this);
task.onPreExecute();
}
}
}

@ -19,49 +19,51 @@
package org.isoron.uhabits.tasks; package org.isoron.uhabits.tasks;
import org.isoron.uhabits.HabitsApplication; import android.support.annotation.*;
import org.isoron.uhabits.commands.CommandRunner;
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
import org.isoron.uhabits.models.Habit;
import javax.inject.Inject; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*;
public class ToggleRepetitionTask extends BaseTask public class ToggleRepetitionTask implements Task
{ {
@Inject @NonNull
CommandRunner commandRunner; private final CommandRunner commandRunner;
public interface Listener { @NonNull
void onToggleRepetitionFinished(); private final Listener listener;
}
private Listener listener; @NonNull
private final Habit habit; private final Habit habit;
private final Long timestamp;
public ToggleRepetitionTask(Habit habit, Long timestamp) private final long timestamp;
public ToggleRepetitionTask(@NonNull Habit habit,
long timestamp,
@NonNull Listener listener)
{ {
this.timestamp = timestamp;
this.habit = habit; this.habit = habit;
HabitsApplication.getComponent().inject(this); this.timestamp = timestamp;
this.listener = listener;
commandRunner = HabitsApplication.getComponent().getCommandRunner();
} }
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
ToggleRepetitionCommand command = new ToggleRepetitionCommand(habit, timestamp); commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
commandRunner.execute(command, habit.getId()); habit.getId());
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
if(listener != null) listener.onToggleRepetitionFinished(); listener.onToggleRepetitionFinished();
super.onPostExecute(null);
} }
public void setListener(Listener listener) public interface Listener
{ {
this.listener = listener; void onToggleRepetitionFinished();
} }
} }

@ -134,14 +134,6 @@ public class BaseSystem
return builder.toString(); return builder.toString();
} }
/**
* Recreates all application reminders.
*/
public void scheduleReminders()
{
new SimpleTask(() -> reminderScheduler.schedule(habitList)).execute();
}
private String getDeviceInfo() private String getDeviceInfo()
{ {
if (context == null) return "null context\n"; if (context == null) return "null context\n";

@ -33,8 +33,6 @@ import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.common.views.*; import org.isoron.uhabits.ui.common.views.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import javax.inject.*;
public class HistoryEditorDialog extends AppCompatDialogFragment public class HistoryEditorDialog extends AppCompatDialogFragment
implements DialogInterface.OnClickListener, ModelObservable.Listener implements DialogInterface.OnClickListener, ModelObservable.Listener
{ {
@ -44,15 +42,18 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
@Nullable @Nullable
HistoryChart historyChart; HistoryChart historyChart;
@Inject
HabitList habitList;
@NonNull @NonNull
private Controller controller; private Controller controller;
private HabitList habitList;
private TaskRunner taskRunner;
public HistoryEditorDialog() public HistoryEditorDialog()
{ {
this.controller = new Controller() {}; this.controller = new Controller() {};
habitList = HabitsApplication.getComponent().getHabitList();
taskRunner = HabitsApplication.getComponent().getTaskRunner();
} }
@Override @Override
@ -66,7 +67,6 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) public Dialog onCreateDialog(@Nullable Bundle savedInstanceState)
{ {
Context context = getActivity(); Context context = getActivity();
HabitsApplication.getComponent().inject(this);
historyChart = new HistoryChart(context); historyChart = new HistoryChart(context);
historyChart.setController(controller); historyChart.setController(controller);
@ -141,28 +141,27 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
private void refreshData() private void refreshData()
{ {
if (habit == null) return; if (habit == null) return;
new RefreshTask().execute(); taskRunner.execute(new RefreshTask());
} }
public interface Controller extends HistoryChart.Controller {} public interface Controller extends HistoryChart.Controller {}
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
public int[] checkmarks; public int[] checkmarks;
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
checkmarks = habit.getCheckmarks().getAllValues(); checkmarks = habit.getCheckmarks().getAllValues();
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
int color = ColorUtils.getColor(getContext(), habit.getColor()); int color = ColorUtils.getColor(getContext(), habit.getColor());
historyChart.setColor(color); historyChart.setColor(color);
historyChart.setCheckmarks(checkmarks); historyChart.setCheckmarks(checkmarks);
super.onPostExecute(aVoid);
} }
} }
} }

@ -37,7 +37,7 @@ import java.util.*;
import javax.inject.*; import javax.inject.*;
public class ListHabitsController public class ListHabitsController
implements ImportDataTask.Listener, HabitCardListController.HabitListener implements HabitCardListController.HabitListener
{ {
@NonNull @NonNull
private final ListHabitsScreen screen; private final ListHabitsScreen screen;
@ -57,6 +57,12 @@ public class ListHabitsController
@Inject @Inject
CommandRunner commandRunner; CommandRunner commandRunner;
@Inject
ReminderScheduler reminderScheduler;
@Inject
TaskRunner taskRuner;
public ListHabitsController(@NonNull HabitList habitList, public ListHabitsController(@NonNull HabitList habitList,
@NonNull ListHabitsScreen screen, @NonNull ListHabitsScreen screen,
@NonNull BaseSystem system, @NonNull BaseSystem system,
@ -74,26 +80,18 @@ public class ListHabitsController
List<Habit> selected = new LinkedList<>(); List<Habit> selected = new LinkedList<>();
for (Habit h : habitList) selected.add(h); for (Habit h : habitList) selected.add(h);
ProgressBar progressBar = screen.getProgressBar(); taskRuner.execute(new ExportCSVTask(habitList, selected, filename -> {
ExportCSVTask task =
new ExportCSVTask(habitList, selected, progressBar);
task.setListener(filename -> {
if (filename != null) screen.showSendFileScreen(filename); if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export); else screen.showMessage(R.string.could_not_export);
}); }));
task.execute();
} }
public void onExportDB() public void onExportDB()
{ {
ExportDBTask task = new ExportDBTask(screen.getProgressBar()); taskRuner.execute(new ExportDBTask(filename -> {
task.setListener(filename -> {
if (filename != null) screen.showSendFileScreen(filename); if (filename != null) screen.showSendFileScreen(filename);
else screen.showMessage(R.string.could_not_export); else screen.showMessage(R.string.could_not_export);
}); }));
task.execute();
} }
@Override @Override
@ -105,20 +103,12 @@ public class ListHabitsController
@Override @Override
public void onHabitReorder(@NonNull Habit from, @NonNull Habit to) public void onHabitReorder(@NonNull Habit from, @NonNull Habit to)
{ {
new SimpleTask(() -> habitList.reorder(from, to)).execute(); taskRuner.execute(() -> habitList.reorder(from, to));
} }
public void onImportData(@NonNull File file) public void onImportData(@NonNull File file)
{ {
ProgressBar bar = screen.getProgressBar(); taskRuner.execute(new ImportDataTask(habitList, file, result -> {
ImportDataTask task = new ImportDataTask(habitList, file, bar);
task.setListener(this);
task.execute();
}
@Override
public void onImportDataFinished(int result)
{
switch (result) switch (result)
{ {
case ImportDataTask.SUCCESS: case ImportDataTask.SUCCESS:
@ -134,8 +124,10 @@ public class ListHabitsController
screen.showMessage(R.string.could_not_import); screen.showMessage(R.string.could_not_import);
break; break;
} }
}));
} }
@Override @Override
public void onInvalidToggle() public void onInvalidToggle()
{ {
@ -177,7 +169,7 @@ public class ListHabitsController
if (prefs.isFirstRun()) onFirstRun(); if (prefs.isFirstRun()) onFirstRun();
new Handler().postDelayed(() -> { new Handler().postDelayed(() -> {
system.scheduleReminders(); taskRuner.execute(() -> reminderScheduler.schedule(habitList));
HabitsApplication.getWidgetUpdater().updateWidgets(); HabitsApplication.getWidgetUpdater().updateWidgets();
}, 1000); }, 1000);
} }

@ -19,7 +19,6 @@
package org.isoron.uhabits.ui.habits.list.model; package org.isoron.uhabits.ui.habits.list.model;
import android.os.*;
import android.support.annotation.*; import android.support.annotation.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
@ -30,8 +29,6 @@ import org.isoron.uhabits.utils.*;
import java.util.*; import java.util.*;
import javax.inject.*;
/** /**
* A HabitCardListCache fetches and keeps a cache of all the data necessary to * A HabitCardListCache fetches and keeps a cache of all the data necessary to
* render a HabitCardListView. * render a HabitCardListView.
@ -44,7 +41,7 @@ public class HabitCardListCache implements CommandRunner.Listener
{ {
private int checkmarkCount; private int checkmarkCount;
private BaseTask currentFetchTask; private Task currentFetchTask;
@Nullable @Nullable
private Listener listener; private Listener listener;
@ -52,30 +49,30 @@ public class HabitCardListCache implements CommandRunner.Listener
@NonNull @NonNull
private CacheData data; private CacheData data;
@Inject
CommandRunner commandRunner;
@NonNull @NonNull
private HabitList allHabits; private HabitList allHabits;
@NonNull @NonNull
private HabitList filteredHabits; private HabitList filteredHabits;
@NonNull private final TaskRunner taskRunner;
private ProgressBar progressBar;
private final CommandRunner commandRunner;
public HabitCardListCache(@NonNull HabitList allHabits) public HabitCardListCache(@NonNull HabitList allHabits)
{ {
this.allHabits = allHabits; this.allHabits = allHabits;
this.filteredHabits = allHabits; this.filteredHabits = allHabits;
this.progressBar = new ProgressBar() {};
data = new CacheData(); data = new CacheData();
HabitsApplication.getComponent().inject(this);
BaseComponent component = HabitsApplication.getComponent();
commandRunner = component.getCommandRunner();
taskRunner = component.getTaskRunner();
} }
public void cancelTasks() public void cancelTasks()
{ {
if (currentFetchTask != null) currentFetchTask.cancel(true); if (currentFetchTask != null) currentFetchTask.cancel();
} }
public int[] getCheckmarks(long habitId) public int[] getCheckmarks(long habitId)
@ -127,14 +124,28 @@ public class HabitCardListCache implements CommandRunner.Listener
public void refreshAllHabits() public void refreshAllHabits()
{ {
if (currentFetchTask != null) currentFetchTask.cancel(true); if (currentFetchTask != null) currentFetchTask.cancel();
currentFetchTask = new RefreshTask(); currentFetchTask = new RefreshTask();
currentFetchTask.execute(); taskRunner.execute(currentFetchTask);
} }
public void refreshHabit(long id) public void refreshHabit(long id)
{ {
new RefreshTask(id).execute(); taskRunner.execute(new RefreshTask(id));
}
public void remove(@NonNull Long id)
{
Habit h = data.id_to_habit.get(id);
if (h == null) return;
int position = data.habits.indexOf(h);
data.habits.remove(position);
data.id_to_habit.remove(id);
data.checkmarks.remove(id);
data.scores.remove(id);
if (listener != null) listener.onItemRemoved(position);
} }
public void reorder(int from, int to) public void reorder(int from, int to)
@ -162,21 +173,7 @@ public class HabitCardListCache implements CommandRunner.Listener
public void setProgressBar(@NonNull ProgressBar progressBar) public void setProgressBar(@NonNull ProgressBar progressBar)
{ {
this.progressBar = progressBar;
}
public void remove(@NonNull Long id)
{
Habit h = data.id_to_habit.get(id);
if(h == null) return;
int position = data.habits.indexOf(h);
data.habits.remove(position);
data.id_to_habit.remove(id);
data.checkmarks.remove(id);
data.scores.remove(id);
if (listener != null) listener.onItemRemoved(position);
} }
/** /**
@ -251,7 +248,7 @@ public class HabitCardListCache implements CommandRunner.Listener
} }
} }
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
@NonNull @NonNull
private CacheData newData; private CacheData newData;
@ -259,10 +256,15 @@ public class HabitCardListCache implements CommandRunner.Listener
@Nullable @Nullable
private Long targetId; private Long targetId;
private boolean isCancelled;
private TaskRunner runner;
public RefreshTask() public RefreshTask()
{ {
newData = new CacheData(); newData = new CacheData();
targetId = null; targetId = null;
isCancelled = false;
} }
public RefreshTask(Long targetId) public RefreshTask(Long targetId)
@ -272,7 +274,13 @@ public class HabitCardListCache implements CommandRunner.Listener
} }
@Override @Override
protected void doInBackground() public void cancel()
{
isCancelled = true;
}
@Override
public void doInBackground()
{ {
newData.fetchHabits(); newData.fetchHabits();
newData.copyScoresFrom(data); newData.copyScoresFrom(data);
@ -282,11 +290,11 @@ public class HabitCardListCache implements CommandRunner.Listener
long day = DateUtils.millisecondsInOneDay; long day = DateUtils.millisecondsInOneDay;
long dateFrom = dateTo - (checkmarkCount - 1) * day; long dateFrom = dateTo - (checkmarkCount - 1) * day;
publishProgress(-1); runner.setCurrentProgress(this, -1);
for (int position = 0; position < newData.habits.size(); position++) for (int position = 0; position < newData.habits.size(); position++)
{ {
if (isCancelled()) return; if (isCancelled) return;
Habit habit = newData.habits.get(position); Habit habit = newData.habits.get(position);
Long id = habit.getId(); Long id = habit.getId();
@ -296,44 +304,27 @@ public class HabitCardListCache implements CommandRunner.Listener
newData.checkmarks.put(id, newData.checkmarks.put(id,
habit.getCheckmarks().getValues(dateFrom, dateTo)); habit.getCheckmarks().getValues(dateFrom, dateTo));
publishProgress(position); runner.setCurrentProgress(this, position);
} }
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onAttached(@NonNull TaskRunner runner)
{ {
currentFetchTask = null; this.runner = runner;
progressBar.hide();
super.onPostExecute(null);
} }
@Override @Override
protected void onPreExecute() public void onPostExecute()
{ {
super.onPreExecute(); currentFetchTask = null;
progressBar.setTotal(0);
new Handler().postDelayed(() -> {
if (getStatus() == Status.RUNNING) progressBar.show();
}, 1000);
} }
@Override @Override
protected void onProgressUpdate(Integer... values) public void onProgressUpdate(int currentPosition)
{ {
int currentPosition = values[0]; if (currentPosition < 0) processRemovedHabits();
else processPosition(currentPosition);
if (currentPosition < 0)
{
progressBar.setTotal(newData.habits.size() - 1);
processRemovedHabits();
}
else
{
progressBar.setCurrent(currentPosition);
processPosition(currentPosition);
}
} }
private void performInsert(Habit habit, int position) private void performInsert(Habit habit, int position)
@ -358,8 +349,7 @@ public class HabitCardListCache implements CommandRunner.Listener
{ {
data.scores.put(id, newData.scores.get(id)); data.scores.put(id, newData.scores.get(id));
data.checkmarks.put(id, newData.checkmarks.get(id)); data.checkmarks.put(id, newData.checkmarks.get(id));
if(listener != null) if (listener != null) listener.onItemChanged(position);
listener.onItemChanged(position);
} }
private void processPosition(int currentPosition) private void processPosition(int currentPosition)

@ -24,13 +24,12 @@ import android.support.annotation.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.commands.*; import org.isoron.uhabits.commands.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.tasks.*;
import org.isoron.uhabits.ui.common.dialogs.*; import org.isoron.uhabits.ui.common.dialogs.*;
import javax.inject.*; import javax.inject.*;
public class ShowHabitController implements ShowHabitRootView.Controller, public class ShowHabitController
HistoryEditorDialog.Controller implements ShowHabitRootView.Controller, HistoryEditorDialog.Controller
{ {
@NonNull @NonNull
private final ShowHabitScreen screen; private final ShowHabitScreen screen;
@ -50,24 +49,21 @@ public class ShowHabitController implements ShowHabitRootView.Controller,
} }
@Override @Override
public void onToolbarChanged() public void onEditHistoryButtonClick()
{ {
screen.invalidateToolbar(); screen.showEditHistoryDialog(this);
} }
@Override @Override
public void onEditHistoryButtonClick() public void onToggleCheckmark(long timestamp)
{ {
screen.showEditHistoryDialog(this); commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp),
null);
} }
@Override @Override
public void onToggleCheckmark(long timestamp) public void onToolbarChanged()
{ {
new SimpleTask(() -> { screen.invalidateToolbar();
ToggleRepetitionCommand command;
command = new ToggleRepetitionCommand(habit, timestamp);
commandRunner.execute(command, null);
}).execute();
} }
} }

@ -41,6 +41,8 @@ public class FrequencyCard extends HabitCard
@BindView(R.id.frequencyChart) @BindView(R.id.frequencyChart)
FrequencyChart chart; FrequencyChart chart;
private TaskRunner taskRunner;
public FrequencyCard(Context context) public FrequencyCard(Context context)
{ {
super(context); super(context);
@ -56,13 +58,14 @@ public class FrequencyCard extends HabitCard
@Override @Override
protected void refreshData() protected void refreshData()
{ {
new RefreshTask().execute(); taskRunner.execute(new RefreshTask());
} }
private void init() private void init()
{ {
inflate(getContext(), R.layout.show_habit_frequency, this); inflate(getContext(), R.layout.show_habit_frequency, this);
ButterKnife.bind(this); ButterKnife.bind(this);
taskRunner = HabitsApplication.getComponent().getTaskRunner();
if (isInEditMode()) initEditMode(); if (isInEditMode()) initEditMode();
} }
@ -75,10 +78,10 @@ public class FrequencyCard extends HabitCard
chart.populateWithRandomData(); chart.populateWithRandomData();
} }
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
RepetitionList reps = getHabit().getRepetitions(); RepetitionList reps = getHabit().getRepetitions();
HashMap<Long, Integer[]> frequency = reps.getWeekdayFrequency(); HashMap<Long, Integer[]> frequency = reps.getWeekdayFrequency();
@ -86,11 +89,10 @@ public class FrequencyCard extends HabitCard
} }
@Override @Override
protected void onPreExecute() public void onPreExecute()
{ {
super.onPreExecute(); int paletteColor = getHabit().getColor();
int color = int color = ColorUtils.getColor(getContext(), paletteColor);
ColorUtils.getColor(getContext(), getHabit().getColor());
title.setTextColor(color); title.setTextColor(color);
chart.setColor(color); chart.setColor(color);
} }

@ -43,6 +43,8 @@ public class HistoryCard extends HabitCard
@NonNull @NonNull
private Controller controller; private Controller controller;
private TaskRunner taskRunner;
public HistoryCard(Context context) public HistoryCard(Context context)
{ {
super(context); super(context);
@ -70,32 +72,14 @@ public class HistoryCard extends HabitCard
@Override @Override
protected void refreshData() protected void refreshData()
{ {
Habit habit = getHabit(); taskRunner.execute(new RefreshTask(getHabit()));
new BaseTask()
{
@Override
protected void doInBackground()
{
int checkmarks[] = habit.getCheckmarks().getAllValues();
chart.setCheckmarks(checkmarks);
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
int color = ColorUtils.getColor(getContext(), habit.getColor());
title.setTextColor(color);
chart.setColor(color);
}
}.execute();
} }
private void init() private void init()
{ {
inflate(getContext(), R.layout.show_habit_history, this); inflate(getContext(), R.layout.show_habit_history, this);
ButterKnife.bind(this); ButterKnife.bind(this);
taskRunner = HabitsApplication.getComponent().getTaskRunner();
controller = new Controller() {}; controller = new Controller() {};
if (isInEditMode()) initEditMode(); if (isInEditMode()) initEditMode();
} }
@ -112,4 +96,26 @@ public class HistoryCard extends HabitCard
{ {
default void onEditHistoryButtonClick() {} default void onEditHistoryButtonClick() {}
} }
private class RefreshTask implements Task
{
private final Habit habit;
public RefreshTask(Habit habit) {this.habit = habit;}
@Override
public void doInBackground()
{
int checkmarks[] = habit.getCheckmarks().getAllValues();
chart.setCheckmarks(checkmarks);
}
@Override
public void onPreExecute()
{
int color = ColorUtils.getColor(getContext(), habit.getColor());
title.setTextColor(color);
chart.setColor(color);
}
}
} }

@ -54,6 +54,8 @@ public class OverviewCard extends HabitCard
private int color; private int color;
private TaskRunner taskRunner;
public OverviewCard(Context context) public OverviewCard(Context context)
{ {
super(context); super(context);
@ -69,7 +71,7 @@ public class OverviewCard extends HabitCard
@Override @Override
protected void refreshData() protected void refreshData()
{ {
new RefreshTask().execute(); taskRunner.execute(new RefreshTask());
} }
private String formatPercentageDiff(float percentageDiff) private String formatPercentageDiff(float percentageDiff)
@ -80,6 +82,7 @@ public class OverviewCard extends HabitCard
private void init() private void init()
{ {
taskRunner = HabitsApplication.getComponent().getTaskRunner();
inflate(getContext(), R.layout.show_habit_overview, this); inflate(getContext(), R.layout.show_habit_overview, this);
ButterKnife.bind(this); ButterKnife.bind(this);
cache = new Cache(); cache = new Cache();
@ -136,10 +139,10 @@ public class OverviewCard extends HabitCard
public float lastYearScore; public float lastYearScore;
} }
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
ScoreList scores = getHabit().getScores(); ScoreList scores = getHabit().getScores();
@ -153,16 +156,14 @@ public class OverviewCard extends HabitCard
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
refreshScore(); refreshScore();
super.onPostExecute(aVoid);
} }
@Override @Override
protected void onPreExecute() public void onPreExecute()
{ {
super.onPreExecute();
color = ColorUtils.getColor(getContext(), getHabit().getColor()); color = ColorUtils.getColor(getContext(), getHabit().getColor());
refreshColors(); refreshColors();
} }

@ -49,6 +49,8 @@ public class ScoreCard extends HabitCard
private int bucketSize; private int bucketSize;
private TaskRunner taskRunner;
public ScoreCard(Context context) public ScoreCard(Context context)
{ {
super(context); super(context);
@ -86,7 +88,7 @@ public class ScoreCard extends HabitCard
@Override @Override
protected void refreshData() protected void refreshData()
{ {
new RefreshTask().execute(); taskRunner.execute(new RefreshTask());
} }
private int getDefaultSpinnerPosition() private int getDefaultSpinnerPosition()
@ -97,6 +99,8 @@ public class ScoreCard extends HabitCard
private void init() private void init()
{ {
taskRunner = HabitsApplication.getComponent().getTaskRunner();
inflate(getContext(), R.layout.show_habit_score, this); inflate(getContext(), R.layout.show_habit_score, this);
ButterKnife.bind(this); ButterKnife.bind(this);
@ -121,10 +125,10 @@ public class ScoreCard extends HabitCard
bucketSize = BUCKET_SIZES[position]; bucketSize = BUCKET_SIZES[position];
} }
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
List<Score> scores; List<Score> scores;
ScoreList scoreList = getHabit().getScores(); ScoreList scoreList = getHabit().getScores();
@ -137,9 +141,8 @@ public class ScoreCard extends HabitCard
} }
@Override @Override
protected void onPreExecute() public void onPreExecute()
{ {
super.onPreExecute();
int color = int color =
ColorUtils.getColor(getContext(), getHabit().getColor()); ColorUtils.getColor(getContext(), getHabit().getColor());
title.setTextColor(color); title.setTextColor(color);

@ -43,6 +43,8 @@ public class StreakCard extends HabitCard
@BindView(R.id.streakChart) @BindView(R.id.streakChart)
StreakChart streakChart; StreakChart streakChart;
private TaskRunner taskRunner;
public StreakCard(Context context) public StreakCard(Context context)
{ {
super(context); super(context);
@ -58,11 +60,12 @@ public class StreakCard extends HabitCard
@Override @Override
protected void refreshData() protected void refreshData()
{ {
new RefreshTask().execute(); taskRunner.execute(new RefreshTask());
} }
private void init() private void init()
{ {
taskRunner = HabitsApplication.getComponent().getTaskRunner();
inflate(getContext(), R.layout.show_habit_streak, this); inflate(getContext(), R.layout.show_habit_streak, this);
ButterKnife.bind(this); ButterKnife.bind(this);
setOrientation(VERTICAL); setOrientation(VERTICAL);
@ -77,28 +80,26 @@ public class StreakCard extends HabitCard
streakChart.populateWithRandomData(); streakChart.populateWithRandomData();
} }
private class RefreshTask extends BaseTask private class RefreshTask implements Task
{ {
public List<Streak> bestStreaks; public List<Streak> bestStreaks;
@Override @Override
protected void doInBackground() public void doInBackground()
{ {
StreakList streaks = getHabit().getStreaks(); StreakList streaks = getHabit().getStreaks();
bestStreaks = streaks.getBest(NUM_STREAKS); bestStreaks = streaks.getBest(NUM_STREAKS);
} }
@Override @Override
protected void onPostExecute(Void aVoid) public void onPostExecute()
{ {
streakChart.setStreaks(bestStreaks); streakChart.setStreaks(bestStreaks);
super.onPostExecute(aVoid);
} }
@Override @Override
protected void onPreExecute() public void onPreExecute()
{ {
super.onPreExecute();
int color = int color =
ColorUtils.getColor(getContext(), getHabit().getColor()); ColorUtils.getColor(getContext(), getHabit().getColor());
title.setTextColor(color); title.setTextColor(color);

Loading…
Cancel
Save