Skip to content
svenmeier edited this page Apr 27, 2012 · 35 revisions

Propoid-util offers convenience working with services and content.

Asynchronous tasks and their observers

TaskService offers an easy management of asynchronous tasks and their observers. Instead of using AsyncTask in your activity , creation and management of tasks is located in a service for the following benefits:

  • being independent of an activity the tasks survive orientation changes
  • tasks started in one activity can published their data to another activity
  • the result of a task can be cached in the service
  • tasks can easily be serialized and/or prioritized
    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 class BarTask(Intent intent) {
          max = intent.getIntExtra("max", 10);
        }

        // asynchronously executed
        protected void onExecute() {
          while (current < max) {
            // expensive calculation
            Thread.sleep(1000);

            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)' 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 include others:

    private class BarTask extends Task {
      public boolean includes(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; 
      }
    }

Preferences

Preference allows convenient typed access to a preference:

    Preference<Boolean> myBoolean = Preference.getBoolean(context, R.string.my_boolean);
    Preference<Integer> myInteger = Preference.getInteger(context, R.string.my_integer);

Thanks to the keys being declares in your strings.xml we have a build-time safe identification of preferences:

   <string name="my_boolean">my_boolean</string>
   <string name="my_integer">my_integer</string>

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.

Clone this wiki locally