Android Handler Usage Analysis, androidhandler

Source: Internet
Author: User

Android Handler Usage Analysis, androidhandler
1. Handler usage

Now, as a customer, there is a need to start the countdown when the Activity interface is opened. After the countdown is over, the new interface will jump (a user with active thinking may immediately think that if the countdown is turned on, similar to the pop-up page of each APP), for example:

As a beginner, it may be okay to directly open a subthread that contains an inverted loop. The specific implementation is as follows:

1.1 Layout interface code:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main2"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.mly.panhouye.handlerdemo.Main2Activity">    <TextView        android:gravity="center"        android:textSize="30sp"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="NO DATA"        android:id="@+id/tv"/></LinearLayout>
1.2 java implementation code:
Public class Main2Activity extends AppCompatActivity {TextView TV; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main2); TV = (TextView) findViewById (R. id. TV); new Thread (new Runnable () {@ Override public void run () {for (int I = 5; I> 0; I --) {TV. setText (String. valueOf (I); try {Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace () ;}/// jump to other interfaces after the timer ends startActivity (new Intent (Main2Activity. this, Main3Activity. class); // Add the finish method to destroy the countdown interface in the task stack, so that the new interface will exit directly when it is rolled back, instead of returning to the interface again to finish ();}}). start ();}

The logic is very simple, but when you click on the interface, you will find that the program has crashed. The error log in logcat is as follows (only the UI thread can change the UI ):

From this we found that in Android development, for example, in the above example, we often use a thread to complete some operations, and then synchronously display the corresponding view control UI, through the above example, we also know that Android cannot directly update the UI through sub-threads. In this case, Android provides an asynchronous message processing mechanism Handler.

2. Handler Implementation Method

Using handler, modify the java code Main2Activity. java as follows:

Package com. mly. panhouye. handlerdemo; import android. content. intent; import android. OS. bundle; import android. OS. handler; import android. OS. message; import android. support. v7.app. appCompatActivity; import android. util. log; import android. widget. textView;/*** Handler: * 1. The Message object to be processed is the Message, which is understood as the encapsulated object of the Message data to be passed. * Message what: Mark, used to differentiate multiple messages * Message arg1, arg2: used to transmit int-type data * Message obj: can transmit any type of Object) */public class Main2Activity extends AppCompatActivity {public static final int UPDATE = 0x1; TextView TV; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main2); TV = (TextView) findViewById (R. id. TV); begin (); // Method for enabling countdown and redirecting to the page} // message Handler, create a subclass object of Handler, the purpose is to Override Handler's method for processing messages (handleMessage () private Handler handler = new Handler () {@ Override public void handleMessage (Message msg) {switch (msg. what) {case UPDATE: TV. setText (String. valueOf (msg. arg1); break ;}}; public void begin () {new Thread (new Runnable () {@ Override public void run () {for (int I = 5; i> 0; I --) {Message msg = new Message (); msg. what = UPDATE; msg. arg1 = I; handler. sendMessage (msg); try {Thread. sleep (1000); // sleep for 1 second} catch (InterruptedException e) {e. printStackTrace ();} // print log. I ("tag", Main2Activity. this + "-" + I);} // jump to other interfaces after the timer ends startActivity (new Intent (Main2Activity. this, Main3Activity. class); // Add the finish method to destroy the countdown interface in the task stack, so that the new interface will exit directly when it is rolled back, instead of returning to the interface again to finish ();}}). start () ;}@ Override protected void onDestroy () {super. onDestroy (); // log printing is used to test the activity to destroy the Log. I ("tag", "destory ");}}
3. Handler implementation principle

Asynchronous Message Processing Using Handler mainly consists of four parts: Message, Handler, MessageQueue, and logoff:

(1) Message: a Message transmitted between threads. It is used for data interaction between different threads. The what field in Message is used to mark and distinguish multiple messages. The arg1 and arg2 fields are used to pass int type data. obj can pass any type of fields.

(2) Handler, used to send and process messages. SendMessage () is used to send messages, and handleMessage () is used to process messages and perform corresponding UI operations.

(3) MessageQueue, A Message Queue (first-in-first-out), used to store messages sent by Handler. One thread has only one message queue.

(4) logoff can be understood as the manager of the Message Queue. When a message exists in MessageQueue, logoff will transmit the message to the handleMessage () method. Similarly, A thread has only one logoff.

Handler implementation principle is as follows:

To use Handler for asynchronous message processing, we need to create a Handler object in the main thread and override the handleMessage () method in combination with the code example and implementation process above, then, when the sub-thread needs to perform UI operations, it creates a Message object and sends the Message through Handlerr. After that, the message will be added to the MessageQueue queue for processing, while logoff will always try to retrieve the message to be processed from the MessageQueue, and finally distribute it back to the handleMessage () method of Handler. Since Halldler is created in the main thread, the code in the handleMessage () method also runs in the main thread to implement the UI thread operation through the Handler mechanism.

4. Handler Memory leakage analysis 4.1 Handler Memory leakage problem:

In the above Handler implementation code, the following issues are actually prompted in Android Studio:

The general meaning is that the Handler class should be static, otherwise Memory leakage will occur. The reason is also clear. Handler is declared as a non-static internal class or anonymous class, which may prevent external class garbage collection (you can understand the gc mechanism of Android ). Excessive Memory leakage causes the program to occupy more memory than the system limit, resulting in OOM (memory overflow) and program errors.

4.2 prevent memory leakage caused by Handler:

Method 1: Program Logic protection:

(1) Stop the corresponding background thread when closing the Activity. When the thread stops, the Handle and external links are cut off. The Activity will be recycled when appropriate.

(2) If Handler is referenced by the delay Message, use the removeCallbacks () method of Handler to remove the Message object from the Message queue.

Method 2: declare Handler as a static class. The static class does not hold the object of the external class, so the Activity can be recycled at will. WeakReference is used here, that is, when the memory is insufficient, the system will destroy the weak/recycle referenced objects to optimize the memory. The optimized code is as follows:

Package com. mly. panhouye. handlerdemo; import android. content. intent; import android. OS. bundle; import android. OS. handler; import android. OS. message; import android. support. v7.app. appCompatActivity; import android. util. log; import android. widget. textView; import java. lang. ref. weakReference; public class Main4Activity extends AppCompatActivity {public static final int UPDATE = 0x1; TextView TV; @ Override pro Tected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main2); TV = (TextView) findViewById (R. id. TV); begin (); // Method for enabling countdown and redirecting to the page} // Handler static internal class private static class MyHandler extends Handler {// weak reference WeakReference <Main4Activity> weakReference; public MyHandler (Main4Activity activity) {weakReference = new WeakReference <Main4Activity> (ac Tietong) ;}@ Override public void handleMessage (Message msg) {Main4Activity activity = weakReference. get (); if (activity! = Null) {activity. TV. setText (String. valueOf (msg. arg1) ;}} private MyHandler handler = new MyHandler (this); public void begin () {new Thread (new Runnable () {@ Override public void run () {for (int I = 5; I> 0; I --) {Message msg = new Message (); msg. what = UPDATE; msg. arg1 = I; handler. sendMessage (msg); try {Thread. sleep (1000); // sleep for 1 second} catch (InterruptedException e) {e. printStackTrace ();} Log. I ("tag", Main4Activity. this + "-" + I);} // jump to other interfaces after the timer ends startActivity (new Intent (Main4Activity. this, Main3Activity. class); // Add the finish method to destroy the countdown interface in the task stack, so that the new interface will exit directly when it is rolled back, instead of returning to the interface again to finish ();}}). start () ;}@ Override protected void onDestroy () {super. onDestroy (); handler. removeCallbacksAndMessages (null); Log. I ("tag", "destory ");}}
5. Summary

In this example, handler is used to implement the countdown page Jump effect. It just briefly introduces handler's usage and precautions, but there are still bugs. If the countdown is not completed, exit the activity, the sub-thread will still run in the background until the jump is completed. The effect and log are as follows:

To solve this problem, I had to deal with the problem. I had to terminate the thread while destroying the countdown activity. I tried many methods and failed to implement them.

In fact, to implement the countdown flash screen effect, you can use the countDownTimer class in Android to implement it. A brief introduction will be provided later.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.