-
Notifications
You must be signed in to change notification settings - Fork 4
Propoid util
Propoid-util offers convenience working with services and content.
TaskService offers an easy management of asynchronous tasks and their observers. Instead of nesting an AsyncTask
in your activity, creation and management of tasks is located in a service for the following benefits:
- being independent of an activity all tasks survive orientation changes
- a task scheduled by one activity can publish its data to another subscribed activity
- tasks can be executed in serial or in parallel
- tasks can be prioritized, merged or subsumed
- the result of a task can be cached in the service
- a task scheduled by network or sensor events can publish its data to any subscribed activity
public class FooService extends TaskService<FooObserver> {
// must be public
public class BarTask extends Task {
private int current;
private int max;
// must be public, argument is optional
public BarTask(Intent intent) {
max = intent.getIntExtra("max", 10);
}
// asynchronously executed
protected void onExecute() {
while (current < max) {
expensiveCalculation();
current++;
// initiate publish
publish();
}
}
// publish on main thread
protected void onPublish(FooObserver observer) {
observer.onBar(current);
}
}
}
To let your activity observe tasks you just have to create a subclass of TaskObserver (it's recommended to put this class besides your service class):
public class FooObserver extends TaskObserver {
public void onBar(int current) {}
}
Your activity can subscribe an observer in onStart()
:
FooObserver observer = new FooObserver() {
// called on main thread
public void onBar(int current) {
mProgress.setProgress(current);
}
};
public void onStart() {
super.onStart();
observer.subscribe(context, FooService.class);
}
A task can be started similar to starting a service. The utility method createIntent(Context, Class<? extends Task>)
creates a suitable intent to let TaskService instantiate the correct task instance:
Intent intent = FooService.createIntent(this, BarTask.class)
intent.putExtra("max", 10);
startService(intent);
Don't forget to unsubscribe the observer in onStop()
:
public void onStop() {
observer.unsubscribe()
super.onStop();
}
By default all Tasks are executed in parallel. But you can easily let your tasks decide how to handle other tasks to be scheduled:
private class BarTask extends Task {
public boolean onScheduling(Task other) {
if (other instanceof BarTask) {
// skip redundant task
return true;
} else if (other instanceof BazTask) {
// must be delayed until this task has finished
delay(other);
return true;
}
// unrelated, let it be scheduled in parallel
return false;
}
}
Preference allows convenient typed access to a preference. Note how to apply a fallback value and a minimal safeguard:
Preference<Boolean> myBoolean = Preference.getBoolean(context, R.string.my_boolean).fallback(true);
Preference<Integer> myInteger = Preference.getInt(context, R.string.my_integer).minimum(2);
if (myBoolean.get()) {
myInteger.set(4);
}
Preference keys are defined as string resources (we recommend to use a separate file res/values/keys.xml
), thus ensuring compile-time safe identification of each preference:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="my_boolean">my_boolean</string>
<string name="my_integer">my_integer</string>
<string name="my_list">my_list</string>
</resources>
You can store and retrieve a list of values too:
Preference<Integer> myList = Preference.getInt(context, R.string.my_list);
myList.setList(Arrays.asList(1, 2, 3, 4));
for (int i : myList.getList()) {
...
}
Most of the time (but not necessarily) you want the user to be able to change the preference:
<CheckBoxPreference
android:key="@string/my_boolean"
android:title="@string/my_boolean_title"
android:summary="@string/my_boolean_summary"
android:defaultValue="true"
/>
<EditTextPreference
android:key="@string/my_integer"
android:title="@string/my_integer_title"
android:summary="@string/my_integer_summary"
android:numeric="integer"
android:defaultValue="10"
/>
Note that in the latter case - an EditTextPreference
with numeric input - any entered String
will automatically be converted to the requested type when accessed via Preference.