-
UI ThreadMobile/Android 2020. 5. 26. 21:52
1. Overview
UI Thread is a special thread started by the Android framework and associated with a single application. There are two alternative names for UI thread so it's either UI thread or sometimes it's called also main thread and to be absolute re girls I must tell you that you are a threat and main threat are not necessarily the same thread. There are situations when these threads will be different. However this distinction is irrelevant to Android application developers and for all practical purposes UI thread and main thread are the same things.
1.1 UI Thread Characteristics
- Started by Android Framework when the application starts
- Terminated only when application's process terminates
- Application's user interface is drawn on UI Thread
- Lifecycle callbacks (e.g. onStart(), onStop()) are executed on UI Thread
- User interaction event handler (e.g. onClick()) are executed on UI Thread
- Changes of user interface must be performed on UI Thread
1.2 Background Thread
Any thread in Android application other than UI thread.
2. User Interface Responsiveness
If you'll do too much work on UI thread, your application will become less responsive.
2.1 UI Responsiveness Warning Signs
All in all you should aim for zero skipped frames in your application and that's one of the most fundamental quality standards of Android applications. And all time-consuming operations should be offloaded to background threads.
- Freezes of user interface, non-smooth animations, etc.
- Notifications about skipped frames in logcat. Whenever your application does too much work on UI thread which causes skipped frames you will get this notification in your logcat.
- Crashes due to Application Not Responding (ANR) error
3. Protection of User Interface from Background Threads
public class SolutionExercise1Fragment extends BaseFragment { private static final int ITERATIONS_COUNTER_DURATION_SEC = 10; public static Fragment newInstance() { return new SolutionExercise1Fragment(); } private Button mBtnCountIterations; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_exercise_1, container, false); mBtnCountIterations = view.findViewById(R.id.btn_count_iterations); mBtnCountIterations.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { countIterations(); } }); return view; } @Override protected String getScreenTitle() { return "Exercise 1"; } private void countIterations() { new Thread(new Runnable() { @Override public void run() { long startTimestamp = System.currentTimeMillis(); long endTimestamp = startTimestamp + ITERATIONS_COUNTER_DURATION_SEC * 1000; int iterationsCount = 0; while (System.currentTimeMillis() <= endTimestamp) { iterationsCount++; } mBtnCountIterations.setText("Iteration: " + iterationsCount); } }).start(); } }
CalledFromWrongThreadException. only the original thread that created if you Hiroki can touch its views. So basically what Android tells us is that only the thread that created the views inside my application should modify them in any way. And recall that the thread that creates views in Android is UI thread. So basically what this Arrow says is that you should modify your views only on UI thread.
3.1 Execution of Code on UI Thread
public class SolutionExercise3Fragment extends BaseFragment { private static final int SECONDS_TO_COUNT = 3; public static Fragment newInstance() { return new SolutionExercise3Fragment(); } private Button mBtnCountSeconds; private TextView mTxtCount; private final Handler mUiHandler = new Handler(Looper.getMainLooper()); @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_exercise_3, container, false); mBtnCountSeconds = view.findViewById(R.id.btn_count_seconds); mTxtCount = view.findViewById(R.id.txt_count); mBtnCountSeconds.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { countIterations(); } }); return view; } @Override protected String getScreenTitle() { return "Exercise 3"; } private void countIterations() { mBtnCountSeconds.setEnabled(false); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= SECONDS_TO_COUNT; i++) { final int count = i; mUiHandler.post(new Runnable() { @Override public void run() { mTxtCount.setText(String.valueOf(count)); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { return; } } mUiHandler.post(new Runnable() { @Override public void run() { mTxtCount.setText("Done!"); mBtnCountSeconds.setEnabled(true); } }); } }).start(); } }
By posting reasonable still UI handler I basically transferred the execution back to UI thread and thus ensure that your code executes on the UI thread of your android application.
4. Reference
'Mobile > Android' 카테고리의 다른 글
Android Architecture (0) 2020.06.02 Garbage Collector, Memory Leaks, and Thread Termination in Android (0) 2020.05.26 Android Processes and Threads (0) 2020.05.26