215 lines
4.5 KiB
Plaintext
215 lines
4.5 KiB
Plaintext
|
Application
|
|||
|
Programming
|
|||
|
Hend Alkittawi
|
|||
|
|
|||
|
Multi-threaded Apps
|
|||
|
Building applications the utilize
|
|||
|
threads
|
|||
|
|
|||
|
INTRODUCTION
|
|||
|
-
|
|||
|
|
|||
|
Recall that a thread is a single sequence of execution, and
|
|||
|
that code running within a single thread will execute one step
|
|||
|
after another.
|
|||
|
|
|||
|
-
|
|||
|
|
|||
|
Every Android app starts life with a main thread. The main
|
|||
|
thread,
|
|||
|
|
|||
|
however,
|
|||
|
|
|||
|
is not a pre-ordained list of steps.
|
|||
|
|
|||
|
Instead it sits in an infinite loop and waits for events
|
|||
|
initiated by the user or the system. Then it excuse code and
|
|||
|
response to those events as they occur.
|
|||
|
-
|
|||
|
|
|||
|
So far, all of our Android apps has been executed on the main
|
|||
|
thread.
|
|||
|
|
|||
|
INTRODUCTION
|
|||
|
-
|
|||
|
|
|||
|
One of the key rules of Android development is to never perform
|
|||
|
time-consuming operations on the main thread of an application.
|
|||
|
|
|||
|
-
|
|||
|
|
|||
|
The second rule is that the code within a separate thread must never, under
|
|||
|
any circumstances, directly update any aspect of the user interface.
|
|||
|
-
|
|||
|
|
|||
|
Any changes to the user interface must always be performed from within the
|
|||
|
main thread.
|
|||
|
|
|||
|
-
|
|||
|
|
|||
|
The Android UI toolkit is not thread-safe. Attempts to work with
|
|||
|
non-thread-safe code from within multiple threads will typically result in
|
|||
|
intermittent problems and unpredictable application behavior!
|
|||
|
|
|||
|
-
|
|||
|
|
|||
|
If the code executing in a thread needs to interact with the user interface,
|
|||
|
it must do so by synchronizing with the main UI thread. This is achieved by
|
|||
|
creating a handler within the main thread, which, in turn, receives messages
|
|||
|
from another thread and updates the user interface accordingly.
|
|||
|
|
|||
|
ANDROID’S MAIN THREAD
|
|||
|
-
|
|||
|
|
|||
|
Regular threads vs the main thread
|
|||
|
A Thread
|
|||
|
|
|||
|
Android’s Main Thread
|
|||
|
|
|||
|
events
|
|||
|
(from Android or User)
|
|||
|
run some code
|
|||
|
|
|||
|
x
|
|||
|
|
|||
|
process an event
|
|||
|
|
|||
|
done
|
|||
|
●
|
|||
|
|
|||
|
reproduced from book figure
|
|||
|
|
|||
|
ANDROID’S MAIN THREAD
|
|||
|
-
|
|||
|
|
|||
|
The main thread in an Android application runs all the code
|
|||
|
that updates the UI, including the code executed and response
|
|||
|
to the different UI related events (activity startup,
|
|||
|
|
|||
|
button
|
|||
|
|
|||
|
presses, …).
|
|||
|
-
|
|||
|
|
|||
|
because the events are all related to the UI and some way,
|
|||
|
the main thread is sometimes called the UI thread.
|
|||
|
|
|||
|
-
|
|||
|
|
|||
|
The event loop keeps the UI code in sequence. It makes sure
|
|||
|
that none of these operations step on each other while still
|
|||
|
ensuring that the code is executed in a timely fashion.
|
|||
|
|
|||
|
BACKGROUND THREADS
|
|||
|
-
|
|||
|
|
|||
|
Sometimes a task takes long time compared to
|
|||
|
other tasks.
|
|||
|
|
|||
|
During that time, the UI will be
|
|||
|
|
|||
|
completely unresponsive,
|
|||
|
|
|||
|
which might result
|
|||
|
|
|||
|
in an Application Not Responding or ANR.
|
|||
|
-
|
|||
|
|
|||
|
An ANR occurs when Android’s watchdog
|
|||
|
determines that the main thread has failed to
|
|||
|
respond to an important event,
|
|||
|
|
|||
|
like pressing
|
|||
|
|
|||
|
the back button.
|
|||
|
-
|
|||
|
|
|||
|
This is not the desired behavior for any
|
|||
|
application.
|
|||
|
|
|||
|
WORD GENERATOR APP
|
|||
|
-
|
|||
|
|
|||
|
Let us look at an app that
|
|||
|
utilizes threads
|
|||
|
|
|||
|
public class WordGenerator {
|
|||
|
public final int wordLength;
|
|||
|
public WordGenerator(int wordLength){
|
|||
|
this.wordLength = wordLength;
|
|||
|
}
|
|||
|
public String generateWord(){
|
|||
|
String generatedWord = "";
|
|||
|
Random rand = new Random();
|
|||
|
for(int i = 0; i < wordLength; i++){
|
|||
|
char randChar = (char) rand.nextInt(256);
|
|||
|
generatedWord = generatedWord + randChar;
|
|||
|
}
|
|||
|
return generatedWord;
|
|||
|
}
|
|||
|
|
|||
|
public class MainActivity extends AppCompatActivity {
|
|||
|
private TextView generatorText;
|
|||
|
private TextView counterText;
|
|||
|
private Button generatorButton;
|
|||
|
private Button counterButton;
|
|||
|
private WordGenerator generator;
|
|||
|
@Override
|
|||
|
protected void onCreate(Bundle savedInstanceState) {
|
|||
|
super.onCreate(savedInstanceState);
|
|||
|
setContentView(R.layout.activity_main);
|
|||
|
generatorButton = findViewById(R.id.generator_button);
|
|||
|
counterButton = findViewById(R.id.counter_button);
|
|||
|
generatorText = findViewById(R.id.generator_text);
|
|||
|
counterText = findViewById(R.id.counter_text);
|
|||
|
generatorButton.setOnClickListener((view) -> startCounter());
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
counterButton.setOnClickListener((view) -> {
|
|||
|
int count = Integer.parseInt(counterText.getText().toString());
|
|||
|
counterText.setText(String.valueOf(count + 1));
|
|||
|
});
|
|||
|
|
|||
|
runOnUiThread(runnable)runs the specified
|
|||
|
action on the UI thread. If the current
|
|||
|
thread is the UI thread, then the action
|
|||
|
is executed immediately. If the current
|
|||
|
thread is not the UI thread, the action
|
|||
|
is posted to the event queue of the UI
|
|||
|
thread.
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
public void startCounter() {
|
|||
|
Thread thread = new Thread(() -> {
|
|||
|
generator = new WordGenerator(5);
|
|||
|
while (true) {
|
|||
|
updateCounterText(generator.generateWord(), generatorText);
|
|||
|
try {
|
|||
|
Thread.sleep(500); // Update every half second
|
|||
|
} catch (InterruptedException e) {
|
|||
|
e.printStackTrace();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
thread.start();
|
|||
|
}
|
|||
|
public void updateCounterText(String text, TextView textView) {
|
|||
|
runOnUiThread(() -> textView.setText(text));
|
|||
|
}
|
|||
|
|
|||
|
DO YOU HAVE ANY
|
|||
|
QUESTIONS?
|
|||
|
|
|||
|
THANK
|
|||
|
YOU!
|
|||
|
|
|||
|
@
|
|||
|
|
|||
|
hend.alkittawi@utsa.edu
|
|||
|
|
|||
|
By Appointment
|
|||
|
Online
|
|||
|
|
|||
|
|