13. What’s On The Main Thread?
Main Thread (UI Thread)
Process
System Event Input Event Service Application UI Drawing
14. What’s On The Main Thread?
Main Thread (UI Thread)
Process
System Event UI Drawing UI Drawing UI Drawing UI Drawing
16ms 16ms 16ms
Animation
15. What’s On The Main Thread?
Main Thread (UI Thread)
Process
System
Event
UI
Drawing
Input Event
16ms 16ms 16ms
UI
Drawing
UI
Drawing
16ms 16ms
16. What’s On The Main Thread?
Main Thread (UI Thread)
Process
System
Event
UI
Drawing
Input Event
16ms 16ms 16ms
UI
Drawing
UI
Drawing
16ms 16msDropped Frame
25. Example
thread = new CustomThread();
//OR
thread = new Thread (new CustomRunnable());
thread.start();
26. Example
public class CustomThread extends Thread {
@Override
public void run() {
doWorkInBackground();
}
}
public class CustomRunnable implements Runnable {
@Override
public void run() {
doWorkInBackground();
}
}
30. How to offload task
●AsyncTask
○ Helps get work on/off the UI thread
●HandlerThread
○ Dedicated thread for API callbacks
●IntentService
○ Helps get intents off the UI thread
●ThreadPool
31. How to offload task
●AsyncTask
○ Helps get work on/off the UI thread
●HandlerThread
○ Dedicated thread for API callbacks
●IntentService
○ Helps get intents off the UI thread
●ThreadPool
38. This Would Also Work
DownloadFilesTask task = new DownloadFilesTask(URL1, URL2, URL3);
task.execute();
public class DownloadFilesTask extends AsyncTask<Void, Integer, Long> {
private URL[] urls;
public DownloadFilesTask(URL... urls) {
this.urls = urls;
}
…
}
44. Example
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));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
@Override
protected void onCancelled(Long result) {
showDialog("Downloaded was cancelled after " + result + " bytes");
}
60. Loader Pattern : Loader
● Abstract class that load data asynchronously,
and monitors its data source.
Loader
Callbacks
Manager
Loader
61. Loader Pattern : Loader
● Abstract class that load data asynchronously,
and monitors its data source.
● Loader that uses AsyncTask
Loader
Async Task
Loader
Callbacks
Manager
Loader
62. Loader Pattern : Loader
● Abstract class that load data asynchronously,
and monitors its data source.
● Loader that uses AsyncTask
● AsyncTaskLoader that queries data from a
ContentProvider and returns a Cursor.
Loader
Async Task
Loader
Cursor Loader
Callbacks
Manager
Loader
66. How Does It Work?
Activity
onCreate()
Loader
Manager
initLoader()
67. How Does It Work?
Activity
onCreate()
Loader
Manager
initLoader()
Loader
Callbacks A
onCreate
Loader()
68. How Does It Work?
Loader
loadIn
Background()
Activity
onCreate()
Loader
Manager
initLoader()
Loader
Callbacks A
onCreate
Loader()
69. How Does It Work?
Loader
loadIn
Background()
Activity
onCreate()
Loader
Manager
initLoader()
Loader
Callbacks A
onCreate() initLoader()
onCreate
Loader()
70. How Does It Work?
Loader
loadIn
Background()
Activity
onCreate()
Loader
Manager
initLoader()
Loader
Callbacks A
onCreate() initLoader()
onCreate
Loader()
71. How Does It Work?
Loader
loadIn
Background()
Activity
onCreate()
onCreate()
Loader
Manager
initLoader()
initLoader()
Loader
Callbacks A
onCreate
Loader()
Loader
Callbacks B
onLoad
Finishes()
87. DemoLoader.java
@Override
public void deliverResult(Long data) {
if (isReset()) {
// The Loader has been reset; ignore the result and invalidate the data.
releaseResources(data);
return;
}
// Hold a reference to the old data so it doesn't get garbage collected.
// We must protect it until the new data has been delivered.
Long oldData = mData;
mData = data;
if (isStarted()) {
// If the Loader is in a started state, deliver the results to the client.
super.deliverResult(data);
}
// Invalidate the old data as we don't need it any more.
if (oldData != null && oldData != data) {
releaseResources(oldData);
}
}
110. By The Way...
Camera.class is deprecated on API 21
Use CameraManager.openCamera(String cameraId,
CameraDevice.StateCallback callback,
Handler handler)
111. Example
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
Camera.open();
//.....
}
};
112. Don’t forget to quit!
handlerThread.quit()
●when you are done
● Or on activities onDestroy().
123. Service Performance
●Services cost time and memory.
○ Creating, scheduling, running, and even destroying services
●Run on the UI thread
124. Make Sure You Need A Service
●Listen and respond to events
○ BroadcastReceiver (even on background)
●Poll a server for data
○ FCM / GCM
●Work detached from UI
○ Use other primitive (saves scheduling)
150. How many threads should can you create?
- Software
- Unlimited
- CPU
- Limited
- Then, prioritize & schedule
151. How many threads should can you create?
●Cores available :
Runtime.getRuntime().availableProcessors();
●Depends on system load
●<= total #cores
152. Thread Priority
- CPU can only handle few at a time
- Decides by priority
- Default : as spawning thread
- Same priority = Same chance for resources
168. 3. Start task
public class PhotoManager {
...
static public PhotoTask startDownload(PhotoView imageView, boolean cacheFlag) {
sInstance.mDownloadThreadPool.
execute(downloadTask.getDownloadRunnable());
}
169. TIP: Pre Start Threads
Threads start on execute().
When constructing the pool with a non-empty queue,
use: prestartCoreThread() or prestartAllCoreThreads()
182. How to offload task
●AsyncTask
○ Helps get work on/off the UI thread
●HandlerThread
○ Dedicated thread for API callbacks
●IntentService
○ Helps get intents off the UI thread
●ThreadPool
199. Avoid non-static inner classes
private static class CountDownHandler extends Handler {
private final WeakReference<DialogCountdown> mDialogCountdownWeakReference;
public CountDownHandler(DialogCountdown dialogCountdown) {
super();
mDialogCountdownWeakReference = new WeakReference<>(dialogCountdown);
}
public void handleMessage(Message msg) {
if(mDialogCountdownWeakReference.get()!=null) {
mDialogCountdownWeakReference.get().onCountDown();
}
}
200. 3. Don’t Cling
●Separate lifecycle from activity’s!
●When back to UI thread, View can be:
○ Removed
○ Distroyed
○ Change properties
●But task still runs and call callbacks
213. What Did We Have Today?
●AsyncTask
○ Helps get work on/off the UI thread
●Loader
○ Handle config. changes during background work
●HandlerThread
○ Dedicated thread for API callbacks
●IntentService
214. What Did We Have Today?
● Services
● Threads priority
●Memory leaks
●Back to UI thread