Advanced #3 threading
-
Upload
vitali-pekelis -
Category
Software
-
view
40 -
download
0
Transcript of Advanced #3 threading
![Page 1: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/1.jpg)
Advanced sessions
Threading
Yossi Segev12/7/2017
3
![Page 2: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/2.jpg)
Hi !
![Page 3: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/3.jpg)
The Largest Android Community
Android Academy - TLV
TLV - Android Academy
Join Us:FundamentalsAdvanced
With designersHackathons
Mentors
![Page 4: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/4.jpg)
Yossi Segev
Android @ Colu
Android Academy
![Page 5: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/5.jpg)
![Page 6: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/6.jpg)
Advanced sessions
Threading
Yossi Segev12/7/2017
3
![Page 7: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/7.jpg)
Application Process
Main Thread
When launching an app...
![Page 8: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/8.jpg)
The Main Thread
UI rendering
Application components
User interaction
Lifecycle callbacks
Main threadQueue
![Page 9: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/9.jpg)
The Main thread is very busy
![Page 10: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/10.jpg)
● When blocked - system shows ANR dialog
● Exception on network operations
● Exclusive interaction with the UI
android.os.NetworkOnMainThreadException
![Page 11: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/11.jpg)
Leaving the Main thread
![Page 12: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/12.jpg)
java.lang.Thread
![Page 13: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/13.jpg)
java.lang.Thread
public class MyThread extends Thread {
@Override
public void run() {
doStuff();
}
}
MyThread myThread = new MyThread();
myThread.start();
![Page 14: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/14.jpg)
java.lang.Thread
public class MyRunnable implements Runnable {
@Override
public void run() {
doStuff();
}
}
Thread myThread = new Thread(new MyRunnable());
myThread.start();
![Page 15: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/15.jpg)
java.lang.Thread
new
MyThread()
start() run()
● One-time use only.
● Dies after executing it’s run() method.
● It’s not legal to start a thread more than once.
![Page 16: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/16.jpg)
How to stop a thread?
![Page 17: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/17.jpg)
Stopping a thread
● Return from the run() method.
![Page 18: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/18.jpg)
Stopping a thread
● Return from the run() method.
● Use cancellation flag.
![Page 19: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/19.jpg)
Cancellation flag
public class MyThread extends Thread {
private boolean mRunning;
@Overridepublic void run() {
mRunning = true;
while (mRunning) {// Do some work...
}}
public void cancel() { mRunning = false; }}
![Page 20: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/20.jpg)
Cancellation flag
public class MyThread extends Thread {
private boolean mRunning;
@Overridepublic void run() {
mRunning = true;
while (mRunning) {// Do some work...
}}
public void cancel() { mRunning = false; }}
![Page 21: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/21.jpg)
Cancellation flag
public class MyThread extends Thread {
private boolean mRunning;
@Overridepublic void run() {
mRunning = true;
while (mRunning) {// Do some work...
}}
public void cancel() { mRunning = false; }}
![Page 22: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/22.jpg)
Stopping a thread
● Return from the run() method.
● Use cancellation flag.
● Call the Thread.interrupt() method.
![Page 23: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/23.jpg)
Thread.interrupt()
Not a magic method!
The implementation is up to us!
![Page 24: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/24.jpg)
Handling interrupt()
public class MyThread extends Thread {
@Overridepublic void run() {
while (!isInterrupted()) {// Do some work...
}}
}
![Page 25: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/25.jpg)
Handling interrupt()
@Override
public void run() {
while (!isInterrupted()) {
// Do some work...
try {
sleep(1000);
} catch (InterruptedException e) {
Log.d("MyThread", "Interrupted!");
break;
}
}
}
![Page 26: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/26.jpg)
Stopping a thread
● Return from the run() method.
● Use cancellation flag.
● Call the Thread.interrupt() method.
!!! DO NOT USE Thread.stop() !!!
![Page 27: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/27.jpg)
Back to the Main thread
![Page 28: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/28.jpg)
Back to the Main thread
We can:
● Activity.runOnUiThread(runnable)
● View.post(runnable)
![Page 29: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/29.jpg)
Back to the Main thread
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
![Page 30: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/30.jpg)
Fixing the crash - CounterActivity
mTextView.post(new Runnable() {
@Override
public void run() {
mTextView.setText("Some data update");
}
});
![Page 31: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/31.jpg)
How does it work??
![Page 32: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/32.jpg)
Activity.java
final Handler mHandler = new Handler();
mUiThread = Thread.currentThread();
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
![Page 33: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/33.jpg)
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
getRunQueue().post(action);
return true;
}
![Page 34: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/34.jpg)
AndroidThreads
Communication mechanism
![Page 35: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/35.jpg)
Android Threads communication - Why?
Java threads communication mechanisms holds a blocking
risk. (ex: Pipes)
Interaction between threads in Android usually involves the
main thread.
Android defines it’s own non-blocking thread
communication mechanism.
![Page 36: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/36.jpg)
Introducing...
![Page 37: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/37.jpg)
The Handler
The Looperand the
MessageQue
ue
![Page 38: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/38.jpg)
android.os.Message
Two types of Messages:
Data Message
Task Message
![Page 39: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/39.jpg)
Message holding data.
android.os.Message
Field Name Description
what int - Unique identifier
when long - timestamp
arg1, arg2 int - “Low cost” parameters
obj Object
data Bundle
![Page 40: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/40.jpg)
Message holding a task (Runnable).
android.os.Message
Field Name Description
callback Runnable task
![Page 41: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/41.jpg)
android.os.Handler
● Creating messages.
● Inserting messages to the queue.
● Removing messages in the queue.
● Consuming messages.
![Page 42: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/42.jpg)
android.os.Looper
● Dispatching messages from its queue to Handlers.
● Only one Looper per thread.
● Keeping its thread alive.
● Thread don’t get a Looper by default.*
![Page 43: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/43.jpg)
Overview
Thread
Looper
MessageQueue
![Page 44: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/44.jpg)
Overview
Thread
Looper
MessageQueue
Handler
![Page 45: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/45.jpg)
Overview
Thread
Looper
MessageQueue
HandlerHandler
![Page 46: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/46.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 47: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/47.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 48: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/48.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 49: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/49.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 50: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/50.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 51: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/51.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 52: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/52.jpg)
Overview
Thread
Looper
HandlerHandler
MessageQueue
![Page 53: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/53.jpg)
Enough theoryLet’s see some code
![Page 54: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/54.jpg)
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming/executing the message.
Overview
![Page 55: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/55.jpg)
FancyThread.java
public class FancyThread extends Thread {
@Override
public void run() {
Looper.prepare();
// Code is missing for simplicity
Looper.loop();
}
}
![Page 56: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/56.jpg)
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming/executing the message.
Overview
![Page 57: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/57.jpg)
Handler creation
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
//Or...
![Page 58: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/58.jpg)
Handler creation
mHandler = new Handler(Looper looper) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do stuff
}
};
mHandler = new Handler(Looper looper, new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false; // return true if msg consumed
}
});
//Or...
![Page 59: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/59.jpg)
FancyThread.java
@Override
public void run() {
Looper.prepare();
mHandler = new Handler(Looper.myLooper(), callback);
Looper.loop();
}
![Page 60: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/60.jpg)
FancyThread.java
public class FancyThread extends Thread {
// …
public Handler getHandler() {
return mHandler;
}
}
![Page 61: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/61.jpg)
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming the message.
Overview
![Page 62: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/62.jpg)
Creating a Message
![Page 63: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/63.jpg)
Creating a Message// Data messages
Message.obtain(Handler h);
Message.obtain(Handler h, int what);
Message.obtain(Handler h, int what, Object o);
Message.obtain(Handler h, int what, int arg1, int arg2);
Message.obtain(Handler h, int what, int arg1, int arg2, Object o);
// Task message
Message.obtain(Handler h, Runnable task);
// Copy constructor
Message.obtain(Message originalMsg);
// Add data Bundle to existing message
msg.setData(Bundle bundle);
![Page 64: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/64.jpg)
Creating a Message with Handler
Message msg = handler.obtainMessage(/*...*/);
![Page 65: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/65.jpg)
Creating a Message
Message message = Message.obtain(); // Return empty message from pool
message.what = 4;
message.arg1 = 100;
message.arg2 = 200;
message.obj = new Object();
message.setData(bundle);
![Page 66: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/66.jpg)
Creating a Message
!! Avoid !!
Message message = new Message();
![Page 67: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/67.jpg)
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming the message.
Overview
![Page 68: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/68.jpg)
Insert a Messageto the queue
![Page 69: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/69.jpg)
Inserting data message to the queue
boolean handler.sendMessage(msg);
boolean handler.sendMessageAtFrontOfQueue(msg);
boolean handler.sendMessageDelayed(msg, 2000);
// And more...
![Page 70: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/70.jpg)
Inserting task message
boolean handler.post(Runnable r)
boolean handler.postAtFrontOfQueue(Runnable r)
boolean handler.postDelayed(Runnable r, long delayMillis)
// And more...
![Page 71: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/71.jpg)
Inserting messages to the queue
// Reference to our Handler
Handler fancyHandler = mFancyThread.getHandler();
// Create data message with what = 1
Message msg = fancyHandler.obtainMessage(1);
// Adding the message to the queue
fancyHandler.sendMessage(msg);
// Adding task message to the queue
fancyHandler.post(new MyRunnable());
![Page 72: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/72.jpg)
Removing a Messagefrom the queue
![Page 73: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/73.jpg)
Removing a Message from the queue
// Remove task message
Handler.removeCallbacks(Runnable r);
// Remove data messages
Handler.removeMessages(int what);
// Remove everything
Handler.removeCallbacksAndMessages(null);
// AND more...
![Page 74: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/74.jpg)
1. A Looper is created and attached to a thread.
2. Handler is created.
3. The Handler create a Message.
4. The Handler insert the Message into the Looper queue.
5. The Handler is consuming the message.
Overview
![Page 75: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/75.jpg)
Consuming - Overriding handleMessage()
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Logger.d("Received message type - 1");
break;
case 2:
Logger.d("Received message type - 2");
break;
}
}
};
![Page 76: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/76.jpg)
Consuming - Handler.Callback
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 1:
Logger.d("Received message type - 1");
return true;
case 2:
Logger.d("Received message type - 2");
return true;
default:
return false;
}
}
The Message is handled?
![Page 77: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/77.jpg)
Consuming task message
// No extra work is needed.
fancyHandler.post(new Runnable() {
@Override
public void run() {
// Will run on the Handler thread.
}
});
![Page 78: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/78.jpg)
Keep it clean!
Don’t forget to call quit()
on your Looper when it is no
longer needed!
![Page 79: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/79.jpg)
FancyActivity.java
@Override
protected void onStop() {
super.onStop();
mFancyThread.getHandler().post(new Runnable() {
@Override
public void run() {
Looper.myLooper().quit();
}
});
}
Option #1
![Page 80: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/80.jpg)
FancyActivity.java
@Override
protected void onStop() {
super.onStop();
mFancyThread.getHandler().sendEmptyMessage(-1);
}
Option #2
![Page 81: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/81.jpg)
FancyThread.java
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case -1:
Looper.myLooper().quit();
return true;
}
}
Option #2
![Page 82: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/82.jpg)
Looper.quit() VS .quitSafely()
.quit() .quitSafely()
● All pending in the queue, Including
messages ready to be dispatched - are
discarded.
● Looper won’t process new messages.
● Discards only messages that are not
ready to dispatch. Ready messages will
be dispatched.
● Looper won’t process new messages.
● Only from API 18.
![Page 83: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/83.jpg)
Phew… Questions?
![Page 84: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/84.jpg)
P.S:
The Main thread is
just a “regular”
thread with a Looper.
![Page 85: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/85.jpg)
The Main thread Looper
The Main thread is the only
thread with a Looper by default.
The Looper cannot be stopped.
You can access the Main thread Looper from anywhere
with: Looper.getMainLooper()
![Page 86: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/86.jpg)
Main thread Handler creation
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "I'm running on the Main thread.");
}
});
![Page 87: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/87.jpg)
Messages passing is a powerful async mechanism but it can be hard to implement from scratch.
Luckily, You don’t have too...
![Page 88: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/88.jpg)
Android Threading primitives
(quick) overview
![Page 89: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/89.jpg)
HandlerThread
Flexible tasks chaining in a queue.
![Page 90: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/90.jpg)
HandlerThread - Example use case
“Our app onboarding flow has 6
different network calls.”
![Page 91: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/91.jpg)
HandlerThread
A Thread with a “free” Looper implementation.
![Page 92: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/92.jpg)
HandlerThread
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
//Make sure to call start() before creating the Handler!
handlerThread.start();
Handler handler = new Handler(mMyHandlerThread.getLooper());
Accessing the thread Looper
![Page 93: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/93.jpg)
Creating a custom HandlerThread
![Page 94: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/94.jpg)
HandlerThread
Override
onLooperPrepared()
for additional setup .
![Page 95: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/95.jpg)
Custom HandlerThreadpublic class MyHandlerThread extends HandlerThread {
private Handler mHandler;
public MyHandlerThread() { super("MyHandlerThread"); }
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandler = new Handler(Looper.myLooper());
}
public void sayHi() {
mHandler.post(new Runnable() {
@Override
public void run() { Log.d("MyHandlerThread", "Hi!"); }
});
}
}
Called after Looper.prepare()
![Page 96: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/96.jpg)
HandlerThread - Stopping
handlerThread.quit();
// or
handlerThread.quitSafely(); // API >= 18
![Page 97: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/97.jpg)
HandlerThread
Remember to quit().
Call start() before calling getLooper()
![Page 98: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/98.jpg)
HandlerThread
Flexible, reusable tasks chaining.
Guarantees thread safety.
Implementation can take a while.
![Page 99: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/99.jpg)
IntentService
“Fire and forget” long-running operations.
![Page 100: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/100.jpg)
IntentService - Example use case
“I want to preload data from my
server to my local DB even
when my app is in the
foreground.”
![Page 101: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/101.jpg)
IntentService
● Subclass of Service.
● Executes operation on a background thread.
● Multiple startService() calls function as a work queue.
● Automatically stops when out of work.
![Page 102: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/102.jpg)
IntentService work queue
startService(Intent i1);
startService(Intent i2);
startService(Intent i3);
onCreate()
onHandleIntent(i1) onHandleIntent(i2) onHandleIntent(i3)
onDestory()
![Page 103: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/103.jpg)
Creating IntentService
![Page 104: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/104.jpg)
IntentService
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService"); // This will be the worker thread name
}
@Override
protected void onHandleIntent(Intent intent) {
// Do some work in the background...
}
} Reference to the calling Intent
![Page 105: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/105.jpg)
IntentService as a work queuepublic class MyIntentService extends IntentService {
public MyIntentService() { super("MyIntentService"); }
public static Intent start(Context context, String name) {
Intent i = new Intent(context, MyIntentService.class);
i.putExtra("extra_name", name);
return i;
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String name = intent.getStringExtra("extra_name");
for (int i = 1 ; i <= 3 ; i ++) {
Log.d("MyIntentService", name + " counts " + i);
}
}
}
Extracting data from Intent
Convenient methodto create Intent with
data.
![Page 106: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/106.jpg)
IntentService as a work queuepublic class MyIntentService extends IntentService {
// …
@Override
public void onCreate() {
super.onCreate();
Logger.d("onCreate() called.”);
}
@Override
public void onDestroy() {
super.onDestroy();
Logger.d("onDestory() called.");
}
}
![Page 107: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/107.jpg)
IntentService as a work queue
startService(MyIntentService.start(this, "John"));
startService(MyIntentService.start(this, "Elvis"));
startService(MyIntentService.start(this, "Sara"));
![Page 108: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/108.jpg)
Log outputD/Academy: onCreate() called.
D/MyIntentService: John counts 1
D/MyIntentService: John counts 2
D/MyIntentService: John counts 3
D/MyIntentService: Elvis counts 1
D/MyIntentService: Elvis counts 2
D/MyIntentService: Elvis counts 3
D/MyIntentService: Sara counts 1
D/MyIntentService: Sara counts 2
D/MyIntentService: Sara counts 3
D/Academy: onDestory() called.
![Page 109: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/109.jpg)
IntentService
Perfect for “fire and forget” long-running operations.
Built-in queue mechanism. Auto stop when work is done.
Is a Service - Less “killable”.
Easy to implement.
Callbacks to UI are complicated. (ResultReceiver)
Cannot cancel.
![Page 110: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/110.jpg)
AsyncTask
Quick “in-and-out” operations.
![Page 111: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/111.jpg)
AsyncTask - Example use case
“I need to fetch a bitmap from a
URL and populate an
ImageView. ”
![Page 112: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/112.jpg)
AsyncTask
Easily get off the Main thread to perform a task.
Return results back to the Main thread to update UI.
![Page 113: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/113.jpg)
AsyncTask
public class MyAsyncTask extends AsyncTask<Params, Progress, Result> {
@Override
protected void onPreExecute() { ...}
@Override
protected Result doInBackground(Params... params) { ...} // Runs in a background thread
@Override
protected void onProgressUpdate(Progress... progress) { ...}
@Override
protected void onPostExecute(Result result) { ...}
@Override
protected void onCancelled(Result result) { ...}
}
![Page 114: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/114.jpg)
DownloadImageTask.javapublic class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView mImageView;
public DownloadImageTask(ImageView imageView) {
mImageView = imageView;
}
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
Bitmap bitmap = downloadImageFromUrl(url);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
mImageView.setImageBitmap(bitmap);
}
}
![Page 115: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/115.jpg)
Executing AsyncTask
DownloadImageTask asyncTask = new DownloadImageTask(imageView);
asyncTask.execute(imageUrl);
// If API >= 11:
// or
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageUrl);
// or
asyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, imageUrl);
// or
asyncTask.executeOnExecutor(myCustomExecutor, imageUrl);
![Page 116: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/116.jpg)
Cancelling running AsyncTask
asyncTask.cancel(true);
@Override
protected Integer doInBackground(Void... params) {
int currentCount = 0;
while (currentCount < 10 && !isCancelled()) { // Checking if canceled periodically
currentCount ++;
}
return currentCount;
}
Also interrupt the thread?
![Page 117: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/117.jpg)
AsyncTask
Don’t let the abstraction fool you!
If you can - specify executor.
Always use cancel()!
Be vigilant. Avoid memory leaks!
Use only as static inner class or as a stand-alone class.
Remember to release any UI reference .
![Page 118: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/118.jpg)
AsyncTask
Useful for quick “in-and-out” operations.
Easy progress and results update on the UI.
Easy to implement.
Easily misused. Handle with caution!
Default implementation changing based on API level.
![Page 119: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/119.jpg)
Loaders
Handle configurations changes gracefully.
![Page 120: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/120.jpg)
Loaders - Example use case
“I’m querying data from a
Content provider.”
![Page 121: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/121.jpg)
Loaders
● Can Load data asynchronously.
● Coordinating with Activity lifecycle.
● Surviving configuration changes.
![Page 122: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/122.jpg)
Loaders
Loader<D>The base class of all Loaders.
AsyncTaskLoader<D>Subclass of Loader<D>, uses AsyncTask to do its
work in the background.
CursorLoader<D>Subclass of AsyncTaskLoader<Cursor>, built to
query ContentProviders and monitor their data.
![Page 123: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/123.jpg)
Loader
Loader
Doing background work ● Loading data asynchronously.
![Page 124: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/124.jpg)
Custom Loader - SimpleLoader.javapublic class SimpleLoader extends AsyncTaskLoader<String> {
public SimpleLoader(Context context) { super(context); }
@Override
protected void onStartLoading() {
super.onStartLoading();
forceLoad(); // Calls loadInBackground()}
@Override
public String loadInBackground() {
// Code runs on a background thread.return data;
}
@Override
public void deliverResult(String data) {
super.deliverResult(data); // "Pushing results out"}
}
![Page 125: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/125.jpg)
CursorLoader example
String searchQuery = "Yossi";
String selection = ContactsContract.Contacts.DISPLAY_NAME + " = ?";
String[] selectionArgs = { searchQuery };
return new CursorLoader(
this, // Context
ContactsContract.Contacts.CONTENT_URI, // Table
projections, // Columns to return
selection, // Selection
selectionArgs, // Selection args
null); // Sort order
}
![Page 126: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/126.jpg)
LoaderCallbacks
LoaderCallBacks
Notify on Loader events
Events:
● New Loader is needed.
● Data is ready.
● Loader is about to reset.
![Page 127: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/127.jpg)
LoaderCallbacks<String>
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new SimpleLoader(this);
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
mTextView.setText(data);
}
@Override
public void onLoaderReset(Loader<String> loader) {
//clear data, reset UI etc...
}
![Page 128: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/128.jpg)
LoaderManager
● Monitor Activity lifecycle.
● Manage Loaders:
➢ Start / Stop / Reset / Retrain
(Activity lifecycle / direct request)
● Invoke LoaderCallBacks.
LoaderManager
Monitor Activity
Manage Loaders
Notify LoaderCallBacks
![Page 129: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/129.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
![Page 130: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/130.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
Getting a reference to the Activity LoaderManager
![Page 131: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/131.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
Instruct LoaderManager to initialize the Loader
![Page 132: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/132.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
Unique Loader ID to init
![Page 133: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/133.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
Optional BundleCan be used for Loader creation
![Page 134: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/134.jpg)
Init Loader
getLoaderManager().initLoader(LOADER_ID, args, LoaderCallbacks);
Interface to report on Loader state changes
![Page 135: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/135.jpg)
initLoader()
LoaderManager
initLoader(LOADER_ID, args, LoaderCallbacks);
No.
onCreateLoader(int id, Bundle args)
Use the existing Loader
Yes.
![Page 136: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/136.jpg)
ThreadPoolExecutor
Call initLoader()only when ready to receive data.
Get fresh data using restartLoader().
![Page 137: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/137.jpg)
Loaders
Coordination with lifecycles.
Built-in results caching mechanism.
Query content providers with ease.
Implementation can be time consuming.
![Page 138: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/138.jpg)
ThreadPoolExecutor
Easy work distribution between multiple threads.
![Page 139: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/139.jpg)
ThreadPoolExecutor - Example use case
“I need to allow my users to
upload multiple pictures from
their gallery simultaneously.”
![Page 140: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/140.jpg)
ThreadPoolExecutor
Managing a pool of thread.
Creating/terminating threads as necessary.
Utilize the Executor interface.
![Page 141: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/141.jpg)
Executor.java
public interface Executor {
void execute(Runnable command);
}
![Page 142: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/142.jpg)
Pre-defined Executors
// Single thread is executing the tasks in order.
Executors.newSingleThreadExecutor();
// Keeping the number of threads constant.
Executors.newFixedThreadPool(n);
// Dynamic size pool - grows/shrinks as needed.
// with 60 sec idle time per thread.
Executors.newCachedThreadPool();
![Page 143: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/143.jpg)
Pre-defined Executors
// Single thread is executing the tasks in order.
Executors.newSingleThreadExecutor(threadFactory);
// Keeping the number of threads constant.
Executors.newFixedThreadPool(n, threadFactory);
// Dynamic size pool - grows/shrinks as needed.
// with 60 sec idle time per thread.
Executors.newCachedThreadPool(threadFactory);
![Page 144: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/144.jpg)
ThreadFactory.java
public interface ThreadFactory {
Thread newThread(Runnable r);
}
![Page 145: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/145.jpg)
MyThreadFactory
public class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(@NonNull Runnable r) {
Thread thread = new Thread(r);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return thread;
}
}
![Page 146: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/146.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
);
![Page 147: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/147.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
Minimum number of threads to keep in the pool
![Page 148: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/148.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
Maximum number of threads to keep in the pool
![Page 149: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/149.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
Time before idle thread is terminated
![Page 150: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/150.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,
RejectedExecutionHandler handler);
The queue type
![Page 151: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/151.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,RejectedExecutionHandler handler
);
ThreadFactory for threads creation
![Page 152: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/152.jpg)
Creating custom Executor
Executor executor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
How to handle rejected task
![Page 153: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/153.jpg)
ThreadPoolExecutor
How to find the right numbers for your needs?
Implement → Measure → Repeat
![Page 154: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/154.jpg)
AsyncTask default parallel executor values since Kitkat (API 19)
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
![Page 155: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/155.jpg)
Executing a task
mExecutor.execute(new MyRunnableTask());
// When task rejection is possible
try {
mExecutor.execute(new MyRunnableTask());
} catch (RejectedExecutionException e) {
// Handle rejection gracefully
}
![Page 156: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/156.jpg)
Stopping ThreadPoolExecutor
mExecutor.shutdown();
mExecutor.shutdownNow();
![Page 157: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/157.jpg)
ThreadPoolExecutor
Implement → Measure → Repeat.
Don’t use the default thread priority.
Remember to handle tasks rejections.
![Page 158: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/158.jpg)
ThreadPoolExecutor
Easy to deal with threads work distribution.
Useful out-of-the-box implementations available.
Implementing efficiently requires time.
![Page 159: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/159.jpg)
![Page 160: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/160.jpg)
One last thing...
![Page 161: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/161.jpg)
Remember - Don’t leak!
![Page 162: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/162.jpg)
Remember - Don’t leak!
Avoid non static inner classes when possible.
![Page 163: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/163.jpg)
Remember - Don’t leak!
Avoid non static inner classes when possible.
Avoid anonymous class declaration when possible.
![Page 164: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/164.jpg)
Remember - Don’t leak!
Avoid non static inner classes when possible.
Avoid anonymous class declaration when possible.
Always implement cancellation policy.
![Page 165: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/165.jpg)
Remember - Don’t leak!
Avoid non static inner classes when possible.
Avoid anonymous class declaration when possible.
Always implement cancellation policy.
Always release references.
![Page 166: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/166.jpg)
Remember - Don’t leak!
Avoid non static inner classes when possible.
Avoid anonymous class declaration when possible.
Always implement cancellation policy.
Always release references.
Be mindful to components lifecycles.
![Page 167: Advanced #3 threading](https://reader033.fdocuments.us/reader033/viewer/2022052606/5aabd1b97f8b9aaf528b51b5/html5/thumbnails/167.jpg)
Thank you.