Remember! Do not perform time-consuming operations in the UI main thread

Remember! Do not perform time-consuming operations in the UI main thread

question

Since the release of Android Ice Cream Sandwich, this question has been spreading on StackOverflow:

My app runs fine on Android 2.x, but always quits on 3.x and 4.x. What's the reason?

This is a great question, after all, developers always hope that applications developed based on old versions of the system are still compatible with new versions of Android. In my opinion, the reasons for the problem may be varied. But most of the time, the reason is very simple: you put a potentially time-consuming operation into the UI thread.

What is the UI thread?

The concept and importance of the main UI thread of an application is something that every Android developer should understand. When an application starts, the system creates a main thread for the application called "main". This main thread (also known as the UI main thread) is mainly responsible for distributing events to the appropriate views or widgets, so it is very important. It is also the thread through which your application interacts with the application's UI. For example, if you click a button on the screen, the UI thread will hand over the click event to the view for processing. After receiving the event, the view will set its pressed state and then send an invalidate request to the event queue. The UI thread will read the queue in turn and tell the view to redraw itself.

Unless your Android application is implemented very well, this single-threaded model will cause extremely low performance. In extreme cases, if the UI thread is responsible for all operations in the entire application, time-consuming operations such as sending network requests or database queries will cause the user interface to be blocked. Before these operations are completed, all events including drawing and touch screen events will not be dispatched. From the user's perspective, the program seems to be stuck.

In these cases, immediate feedback is critical. Studies have shown that 0.1s is the threshold for users to feel that the system is smooth. Anything slower than the threshold is considered latency (Miller 1968; Card et al. 1991). Although 1 second may not seem like a big deal, in Google Play, even a tenth of a second can be the difference between a good review and a bad one. Even worse, if the UI thread is blocked for more than 5 seconds, the user will receive an "Application Not Responding" (ANR) dialog box and be forced to quit.

Why Android crashes apps

The main reason why the application runs well on 2.x systems and crashes on 3.0 and above platforms is that 3.0 and above platforms are more strict in handling UI thread resource abuse. For example, when the 3.0 platform detects a network request in the UI thread, it will throw a NetworkOnMainThreadException:

E/AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.ExampleActivity}: android.os.NetworkOnMainThreadException

This is also well explained in the Android developer website documentation:

When an application attempts to perform a network operation in the main thread, NetworkOnMainThreadException is thrown. This is only thrown when running the Honeycomb SDK and higher. Earlier versions of the SDK allow network operations in the main event loop thread, but it is highly discouraged.

Here are some operations that ICS and Honeycomb do not allow on the UI thread:

Open a socket connection (ie new Socket()).

HTTP requests (ie HTTPClient and HTTPUrlConnection).

Trying to connect to a remote MYSQL database.

Download a file (ieDownloader.downloadFile()).

If you want to do something in the UI thread, be sure to package it into a worker thread. The simplest way is to use AsyncTask, which allows you to do some asynchronous operations in your user interface. AsyncTask will put the blocking operation into the worker thread and return the result to the UI thread, and you don't need to handle any thread-related work.

in conclusion

I decided to write this topic because I saw this problem countless times on StackOerflow and other forums. The main source of problems is time-consuming operations performed on the UI thread. In order to ensure that the user interface remains smooth, it is necessary to perform socket connections, HTTP requests, file downloads and other time-consuming operations in a separate thread. The easiest way to do this is to package the operations into AsyncTask, which will help you start new threads and let them interact with your user interface asynchronously.

Helpful Links

These materials may help you get familiar with AsyncTask

AsyncTask documentation

Multithreading For Performance

<<:  Talking about Tint in Android Material Design

>>:  6 Things I Wish I Knew When I Wrote My First Android App

Recommend

How to create a hit product?

A good product can increase the probability of be...

Bank Brand Marketing Methodology

There are more than 4,000 banks in my country, in...

President Xi Jinping delivers 2024 New Year message

On the eve of the New Year, President Xi Jinping ...

10w+ new followers in 4 days, how to increase followers by splitting?

Today I want to talk to you about the entire clos...

25 “Empty-Empty” APP Promotion Methods, You Deserve It!

Due to various reasons, our company is not like m...

Is there another core hidden in the Earth's inner core?

The Earth is the common home of all living things...