2. Threading When a component is started and no other component
has been created for the same application, the system creates a new
process. When a component is started and other components of the
same application are created, the component runs in the same
process of others. Each process consists of one or more Thread.
There is a Main Thread for each process. All components in the same
process are performed in the Main Thread. The unique identifier of
the process in the system is defined by the package declared in the
Manifest. Processes
3. Threading By default, all components of an application are
executed in the same process. This management should not be
changed, but you can start every single component in a custom
process by defining its unique identifier in the Manifest: Es.
Gestione dei Processi
4. Threading The system manages the processes trying to keep
them as long as possible, but when the system needs memory to start
another process it must delete some of them. To determine which of
them can bedeleted, the system manages a hierarchy of importance of
the processes. There are 5 importance levels to do this: Foreground
Processes Visible Processes Service Processes Background Processes
Empty Processes Process LifeCycle
5. Threading Android UI Toolkit is not thread-safe: the Main
Thread is the onlyone that can handle GUI (this is also called the
UI Thread). All components run in the same process and share the
same Main Thread. For this, long operations like HTTP calls or DB
query must be executed on a secondary thread, and not on the Main
Thread because these would block the GUI. Until Android 2.3.x this
was possible (although after a few seconds the user displayed an
Application Not Responding Dialog), while from HoneyComb if you run
this type of operation on the Main Thread is generated a
NetworkOnMainThreadException. Main Thread
6. Threading The long running operations must be carried out on
a secondary thread called Background Thread or Worker Thread.
public void onClick(View v) { new Thread(new Runnable() { public
void run() { Bitmap b
=loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b); } }).start(); } This sample code
violates a platform rule because it changes the UI from a Secondary
Thread. Background Thread
7. Threading To change the UI from a background thread, you can
use the following methods: Activity.runOnUiThread(Runnable)
View.post(Runnable) View.postDelayed(Runnable, long)
Handler.post(Runnable) public void onClick(View v) { new Thread(new
Runnable() { public void run() { final Bitmap bitmap =
loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() { public void run() {
mImageView.setImageBitmap(bitmap); } }); } }).start(); } Background
Thread
8. Threading With the increasing complexity of operations, this
type of management becomes more and more complicated and difficult
to maintain. To simplify this management Android provides the
AsyncTask object. A AsyncTask runs the code that runs in the
background thread and the one in the Main Thread. public void
onClick(View v) { new
DownloadImageTask().execute("http://example.com/image.png"); }
private class DownloadImageTask extends AsyncTask { protected
Bitmap doInBackground(String... urls) { return
loadImageFromNetwork(urls[0]); } protected void
onPostExecute(Bitmap result) { mImageView.setImageBitmap(result); }
} AsyncTask
9. Threading A AsyncTask is defined by 3 generics types and 4
steps: Types: Params: input type Progress: update type Result:
result type Steps: onPreExecute: MT executed before the secondary
thread to show the user a possible graphical update doInBackground:
BT long running operations to be executed in background. It can
invoke the publishProgress(Progress...) method to notify the MT the
updating progress (invoking onProgressUpdate()) onProgressUpdate:
MT it0s used to show the progress to the user onPostExecute: MT it
handles the result returned by the doInBackground() method
AsyncTask
10. Threading Rules to use a AsyncTask (otherwise an
IllegalStateException is thrown): It must be instantiated on Main
Thread It must be started on Main Thread (AsyncTask.execute()) The
steps cannot be invoked manually It can be executed only one time
Until GingerBread (Android 2.3.x) the AsyncTask execution created
more Threads in Thread Pool for a parallel execution. From
HoneyComb (Android 3.0) every Task is executed serially in a
Background Thread to limit errors. If you want to use parallelized
tasks you need to use:
AsyncTask.executeOnExecutor(THREAD_POOL_EXECUTOR) AsyncTask -
Regole
11. Threading private class DownloadFilesTask extends AsyncTask
{ @Override protected void onPreExecute() { setProgressPercent(0);
} @Override protected Long doInBackground(URL... urls) { int count
= urls.length; long totalSize = 0; for (int i = 0; i < count;
i++) { totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100)); if
(isCancelled()) break; } return totalSize; } @Override protected
void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]); } @Override protected void
onPostExecute(Long result) { showDialog("Downloaded " + result + "
bytes"); } } AsyncTask - Example
12. Threading LIMIT: When a task is executed in an Activity and
Activity Recreation occurs, the Task is deleted along with the rest
of the Activity and must then be rebooted again and restarted.
SOLUTION 1: the use of application context instead of the Activity
one SOLUTION 2: the use of Loaders LIMIT: A AsyncTask hasn't got a
method to retrieve the result. SOLUTION 1: the use of an interface
SOLUTION 2: the implementation of a Task as an Activity anonymous
inner class SOLUTION 3: the use of Loaders AsyncTask - Limits
13. Threading They are available since HoneyComb (Android 3.0):
Available for every single Activity or Fragment Useful for
asynchronous loading of data They handle data source and send new
results if they change Independents from Activity or Fragment
lifecycle: they store result data not to be restart after Activity
recreation. Loaders
14. Threading LoaderManager: Utility class used to manage every
Loader instance of an Activity or Fragment. There is only one
LoaderManager a Activity or Fragment.
LoaderManager.LoaderCallbacks: a callback interface to retrieve the
result data Loader: abstract class that executes the operations.
There are Loader subclasses to simplify AsyncTask or Cursor
management or you can develop your custom Loader. AsyncTaskLoader:
Loader subclass that uses a AsyncTask to execute the operations
CursorLoader: AsyncTaskLoader subclass to execute queries of a
ContentProvider Loaders - Classes
15. Threading There is only one LoaderManager for Activity or
Fragment, then typically Activity.onCreate() or
Fragment.onActivityCreated() initializes a new Loader or retrieve a
previously initiated one. public void onCreate(Bundle
savedInstanceState) { getLoaderManager().initLoader(0, null, this);
} LoaderManager.initLoader() parameters: Int: unique ID to identify
the Loader instance Bundle: Key-Value Pair to pass any additional
parameter LoaderManager.LoaderCallbacks: result managing instance.
Loaders - Start
16. Threading The call to LoaderManager.initLoader() means that
a Loader is initiated and active. There are 2 cases: If the
specified ID already exists, the last Loader is reused If the ID
doesn't exist, the LoaderManager.LoaderCallbacks.onCreateLoader()
is invoked so a new Loader instance is created. If you want to
force the reload of an already used Loader you can use the
LoaderManager.restartLoader() method using the same ID:
getLoaderManager().restartLoader(0, null, this); Loaders -
Avvio
17. Threading LoaderManager.LoaderCallbacks methods:
onCreateLoader(): it returns a new Loader with the specified ID
onLoadFinished(): it's called when an already run Loader has
finished its operations and it returns the result onLoadReset():
called when an already active Loader is reloaded so the old data is
no longer needed. Loaders - Callbacks
18. Threading public class WeatherDetailProviderLoader extends
AsyncTaskLoader { private String location; public
WeatherDetailProviderLoader(Context context, String location) {
super(context); this.location = location; } @Override public
Forecast loadInBackground() { return
WeatherProviderUtils.query(getContext(), location); } } Loaders -
Example
19. Threading public class WeatherFragment extends Fragment
implements LoaderCallbacks { @Override public void
onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(0, null, this); } @Override public
Loader onCreateLoader(int arg0, Bundle arg1) { return new
WeatherDetailProviderLoader(getActivity(), location)); } @Override
public void onLoadFinished(Loader arg0, Forecast result) {
adaptWeather(result); } @Override public void onLoaderReset(Loader
arg0) { adaptWeather(null); } } Loaders - Example