You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Dec 17, 2020. It is now read-only.
An easy to use micro-library for easy asynchronous background tasking with callbacks to the UI. This library is based on the Android AsyncTask implementation but with support for configuration changes (orientation) and callbacks to the UI. It also support custom Executors.
2
+
Android-Retainable-Tasks is an easy to use mini-library for easy asynchronous background tasking with callback support to the UI. This library is based on the Android `AsyncTask` implementation but with support for retaining tasks and therefor surviving configuration changes (orientation).
3
3
4
-
Usage
5
-
--------
6
-
Extend the `Task` class to build a custom task. The `Task` class is heavily based on the default Android `AsyncTask` class and you will need to override the `doInBackground` method. Note that the `Task` class doesn't come with a generic type for input parameters, you should provide input when constructing the `Task` instance (using the constructor for example).
4
+
1.[Basic usage](#1-basic-usage)
5
+
2.[How it works](#2-how-it-works)
6
+
3.[Advanced usage](#3-advanced-usage)
7
+
4.[FAQ](#4-faq)
8
+
9
+
## 1. Basic usage
10
+
---
11
+
In order to, execute a task which modifies the user-interface and to retain it across configuration changes you will need to do three things:
12
+
13
+
1. Create an implementation of the `Task` class;
14
+
2. Execute the task using the `TaskHandler` in an`Activity` which implements the `Callback` interface;
15
+
3. Retain the task when configuration changes by overriding the `onStart()` method and calling the `TaskHandler.attachListener()` method;
16
+
17
+
The Activity's `TaskHandler` makes sure that tasks can be retained across configuration changes and is responsible for removing the `Callback` listener when the Activity's user-interface is no longer valid. You are however responsible for re-attaching a new `Callback` listener when the Activity 's user-interface is restarted.
18
+
19
+
### 1.1 Creating the task
20
+
21
+
You will need to extend the `Task` class to create a custom task. The `Task` class is heavily based on the default Android `AsyncTask` class and you will need to override at least the `doInBackground` method and provide an appropriate constructor.
22
+
23
+
>**Note:**
24
+
>A`Task` doesn't come with a generic type for input parameters like the Android `AsyncTask`, instead you should provide input when constructing the `Task` (using the constructor for example).
Then execute the task using the TaskExecutor. You can also execute tasks using a custom Executor.
48
+
49
+
### 1.2 Executing the task
50
+
Before you can execute the `ExampleTask` you first need to get the current Activity's `TaskHandler`. A `TaskHandler` keeps references to tasks and executes them. You can obtain the current Activity's `TaskHandler` using the `TaskHandler.getActivityTaskHandler()` method:
Then you can execute the task using the `TaskHandler.execute()` method. This method needs two arguments, the task to execute and a `Callback` listener to send feedback to. Preferably your activity implements the `Callback` interface, but this isn't necessarily needed.
When the configuration changes (device rotates) the Activity's `TaskHandler` will automatically remove the `Callback` listeners from all active tasks. This is needed otherwise the tasks could leak Activity, Fragment or other references.
84
+
85
+
> **In-depth:**
86
+
> The `TaskHandler` will automatically remove the `Callback` listeners when the Activity is stopping (`onStop()`). At this moment the user-interface has become *"unstable"*, for example, when this happens the FragmentManager refuses to add new Fragments because the Activity's `onSaveInstanceState()` method has already been called. If the `Callback` listener is not removed by the `TaskHandler` before this point, then a `DialogFragment.show()` call will throw an exception when called in the `onPostExecute()` method. This is why the `Callback` listeners are removed when the Activity stops.
87
+
88
+
To retain the task when your Activity is recreated you will need to re-attach a (new) `Callback` listener using the `TaskHandler.attachListener()` method. The best place to do this is in the `onStart()` method right after the user-interface has been created.
89
+
90
+
34
91
```java
35
-
//Alias for calling executeParallel
36
-
TaskExecutor.execute(newExampleTask());
92
+
@Override
93
+
publicvoid onStart(){
94
+
super.onStart();
95
+
//Re-attach the this Activity as listener for task
Using the TaskExecutor directly (like in the above example) means that you won't get any feedback to the UI.
100
+
## 2. How it works
101
+
---
102
+
**Retaining tasks**
103
+
Tasks retained using the described method are stored in a *"no-ui-fragment"* this fragment retained across configuration changes and is added to your Activity's `FragmentManager` the first time you call `TaskHandler.getActivityTaskHandler()`. This fragment is from that point on bound to the Activity's life-cycle and holds an internal `TaskHandler`. The fragment makes sure that the internal `TaskHandler` removes all `Callback` listeners as soon as the Activity is stopping (`onStop()`).
104
+
105
+
**Task without callback finishes**
106
+
When a Task doesn't have a `Callback` listener to deliver it's results to it will skip the delivery and redeliver the results as soon as a new listener is attached. If you call the `TaskHandler.attachListener()` method in the `onStart()` method, then the listener will be fired and you need to be sure that the user-interface is ready.
107
+
108
+
Only the `onPostExecute()` and `onCanceled()` methods will be redelivered, other methodes won't be redelivered.
40
109
41
-
The preferred way to use a the `Task` class is by using the `TaskHandler.getActivityTaskHandler(FragmentManger)` method which returns a TaskHandler. The TaskHandler which is returned is loosely coupled to the Activity life-cycle using a internal Fragment which is retained across configuration changes. The `TaskHandler` makes sure you can retain your tasks across configuration changes.
110
+
**Task and Callback life-cycle**
111
+
A `Task` basically has four life-cycle methods:
112
+
113
+
*`onPreExecute()`*[ui-thread]*
114
+
*`doInBackground()`*[executor-thread]*
115
+
*`onProgressUpdate()`*[ui-thread]*
116
+
*`onPostExecute()` or `onCanceled()`*[ui-thread]*
117
+
118
+
A `Callback` listener has the same life-cycle methods as the`Task` and reflects those methods to, for example, an Activity. All `Callback` methods are executed on the user interface thread. When a `Callback` listener is attached to the task, both the `Callback` and the `Task` methods will be called. But when the listener is detached from the task only the tasks methods will be called. With the exception of the `onPostExecute()` and `onCanceled()` methods which can be redelivered.
119
+
120
+
121
+
## 3. Advanced usage
122
+
---
123
+
Besides the basics there are some more advanced API's you will probably need.
124
+
125
+
**Getting task results**
126
+
Unlike the default Android `AsyncTask` implementation you don't get `Task` results as a parameter, instead you will need to call the `Task.getResult()` method, which returns the tasks result.
127
+
128
+
**Getting the tasks current state**
129
+
The Android `AsyncTask` API provides the `AsyncTask.getStatus()` method which returns an enum value which can be used to determinate the tasks current state. Instead of using that method combined with an enum you can use on of the following methods:
130
+
131
+
*`isFinished()`
132
+
*`isRunning()`
133
+
*`isReady()`
134
+
*`isResultDelivered()`
135
+
*`isCanceled()`
136
+
137
+
**Getting the tasks last progress update**
138
+
To get the tasks most recent progress update use the `getLastKnownProgress()` method.
139
+
140
+
**AdvancedCallback**
141
+
If you need the `onProgressUpdated` and `onCanceled` callback methods you can implement the `AdvancedCallback` interface, which is an extension of the `Callback` interface.
142
+
143
+
**TaskExecutor & Executor**
144
+
You can also execute tasks without using a `TaskHandler` this means that you are responsible for removing and setting the `Callback` listener. Executing tasks without using the `TaskHandler` is handy when you don't need to get any feedback to the Activity's user-interface.
//Attach this activity as listener for the Task identified by tag TASK_DEMO
56
-
getTaskHandler().attachListener(TASK_DEMO, this);
57
-
}
163
+
## 4. FAQ
58
164
59
-
publicvoidonClick(Viewv) {
60
-
//Create a new task and execute it through the TaskHandler,
61
-
//making this activity instance the tasks listener.
62
-
ExampleTask task =newExampleTask(TASK_DEMO);
63
-
getTaskHandler().execute(task, this);
64
-
}
165
+
**Why does the Task class still have the onPostExecute and onPreExecute etc. methods?**
166
+
Although the `Callback` interface provides these methods sometimes you don't need any callback to the Activity's user-interface, at that moment the Task methods come in handy.
0 commit comments