ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UI Thread
    Mobile/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

    https://medium.com/@techyourchance

    '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

    댓글

Designed by Tistory.