The article I bring to you today is to analyze the usage and steps of HandlerThread in Android through example code. Friends who need it can refer to it.
HandlerThread Introduction:
We know that the Thread thread is a one-time consumer product. When the Thread thread completes a time-consuming task, the thread will be automatically destroyed. If I have another time-consuming task that needs to be performed at this time, we have to re-create the thread to perform the time-consuming task. However, there is a performance problem: creating and destroying threads multiple times consumes
system resources. In order to understand this problem, we can build a loop thread Looper Thread ourselves. When a time-consuming task is placed in the loop thread, the thread executes the time-consuming task. After the execution, the loop thread is in a waiting state. Until the next new time-consuming task is put in. This avoids the
performance problems caused by creating Thread threads multiple times. Maybe you can build a loop thread yourself, but I can tell you good news. There is actually a loop thread framework in the Aandroid SDK
. At this point you just need to master how to use it and that’s it! Of course it is our protagonist HandlerThread today! Next, let HandlerThread come on stage, applause~~
The parent class of HandlerThread is Thread, so HandlerThread is actually a thread, but it only helps you implement a Looper loop internally. So let's
first understand how Handler is used!
HandlerThread usage steps:
1. Create an instance objectHandlerThread handlerThread = new HandlerThread("handlerThread");
The above parameters can be arbitrary
String
, the main function of the parameter is to mark the name of the current thread.
2. Start the HandlerThread threadhandlerThread.start();
3. Build a loop message processing mechanism
Handler subHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { //实现自己的消息处理 return true; } });The third step is to create a Handler object, use the looper object in the above HandlerThread as the Handler parameter, and then Rewrite the
handlerMessage method in the Handler's Callback interface class to handle time-consuming tasks.
Summary: The order of the above three steps cannot be messed up, and the steps must be strictly followed. At this point, we can call subHandler to send time-consuming tasks in the form of
send messagesto the thread
HandlerThread for execution. The implication is that the handlerMessage method in the Callback interface class in subHandler is actually executed in the worker thread. HandlerThread instance:
package com.example.handlerthread; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Handler mSubHandler; private TextView textView; private Button button; private Handler.Callback mSubCallback = new Handler.Callback() { //该接口的实现就是处理异步耗时任务的,因此该方法执行在子线程中 @Override public boolean handleMessage(Message msg) { switch (msg.what) { case 0: Message msg1 = new Message(); msg1.what = 0; msg1.obj = java.lang.System.currentTimeMillis(); mUIHandler.sendMessage(msg1); break; default: break; } return false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); HandlerThread workHandle = new HandlerThread("workHandleThread"); workHandle.start(); mSubHandler = new Handler(workHandle.getLooper(), mSubCallback); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //投放异步耗时任务到HandlerThread中 mSubHandler.sendEmptyMessage(0); } }); } }HandlerThread source code analysis
Construction method
/** * Handy class for starting a new thread that has a looper. The looper can then be * used to create handler classes. Note that start() must still be called. */ public class HandlerThread extends Thread { //线程优先级 int mPriority; //当前线程id int mTid = -1; //当前线程持有的Looper对象 Looper mLooper; //构造方法 public HandlerThread(String name) { //调用父类默认的方法创建线程 super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } //带优先级参数的构造方法 public HandlerThread(String name, int priority) { super(name); mPriority = priority; } ............... }Analysis: This class gives a description at the beginning: This class is used to create a thread with a Looper loop, and the Looper object is used to create a Handler object. It is worth noting that you need to call the start() method to start the thread before creating the Handler
object. Maybe some people here have questions? Why do we need to call the start() method before we can create a Handler? We will answer this later.
The above code comments are very clear. The HandlerThread class has two constructors. The difference is to set the priority parameter of the current thread. You can set the priority
according to your own situation, or you can use the default priority.
HandlerThrad's run method
public class HandlerThread extends Thread { /** * Call back method that can be explicitly overridden if needed to execute some * setup before Looper loops. */ protected void onLooperPrepared() { } @Override public void run() { //获得当前线程的id mTid = Process.myTid(); //准备循环条件 Looper.prepare(); //持有锁机制来获得当前线程的Looper对象 synchronized (this) { mLooper = Looper.myLooper(); //发出通知,当前线程已经创建mLooper对象成功,这里主要是通知getLooper方法中的wait notifyAll(); } //设置当前线程的优先级 Process.setThreadPriority(mPriority); //该方法实现体是空的,子类可以实现该方法,作用就是在线程循环之前做一些准备工作,当然子类也可以不实现。 onLooperPrepared(); //启动loop Looper.loop(); mTid = -1; } }Analysis: The comments in the above code have been clearly written. The main function of the above run method is to call Looper. prepare and Looper.loop build a loop thread. It is worth mentioning that the onLooperPrepared method is called before starting the loop in the run method. The implementation of this method is empty, and users can implement this method in subclasses. The function of this method is to
do some initialization work before the thread loop. Of course, you may not implement this method, depending on the requirements. It can also be seen that Google engineers also consider the scalability of the code when writing the code. Niu B!
Other methods of HandlerThread
getLooper gets the Looper object of the current thread/** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { //如果线程不是存活的,则直接返回null if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. //如果线程已经启动,但是Looper还未创建的话,就等待,知道Looper创建成功 synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
null, it means that the current thread has been created successfully, but the Looper object has not yet been created. Therefore, the wait method will be called here. Go and wait. When the notifyAll method in the run method is called,
notifies the wait method of the current thread to wait for the end, jumps out of the loop, and obtains the value of the mLooper object.
总结:在获得mLooper对象的时候存在一个同步的问题,只有当线程创建成功并且Looper对象也创建成功之后才能获得mLooper的值。这里等待方法wait和run方法中的notifyAll方法共同完成同步问题。
quit结束当前线程的循环
/** * Quits the handler thread's looper. * <p> * Causes the handler thread's looper to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } //安全退出循环 public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; }
分析:以上有两种让当前线程退出循环的方法,一种是安全的,一中是不安全的。至于两者有什么区别? quitSafely方法效率比quit方法标率低一点,但是安全。具体选择哪种就要看具体项目了。
总结:
1.HandlerThread适用于构建循环线程。
2.在创建Handler作为HandlerThread线程消息执行者的时候必须调用start方法之后,因为创建Handler需要的Looper参数是从HandlerThread类中获得,而Looper对象的赋值又是在HandlerThread的run方法中创建。
相信看了这些案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
相关阅读:
The above is the detailed content of HandlerThread source code detailed Android example. For more information, please follow other related articles on the PHP Chinese website!

To protect the application from session-related XSS attacks, the following measures are required: 1. Set the HttpOnly and Secure flags to protect the session cookies. 2. Export codes for all user inputs. 3. Implement content security policy (CSP) to limit script sources. Through these policies, session-related XSS attacks can be effectively protected and user data can be ensured.

Methods to optimize PHP session performance include: 1. Delay session start, 2. Use database to store sessions, 3. Compress session data, 4. Manage session life cycle, and 5. Implement session sharing. These strategies can significantly improve the efficiency of applications in high concurrency environments.

Thesession.gc_maxlifetimesettinginPHPdeterminesthelifespanofsessiondata,setinseconds.1)It'sconfiguredinphp.iniorviaini_set().2)Abalanceisneededtoavoidperformanceissuesandunexpectedlogouts.3)PHP'sgarbagecollectionisprobabilistic,influencedbygc_probabi

In PHP, you can use the session_name() function to configure the session name. The specific steps are as follows: 1. Use the session_name() function to set the session name, such as session_name("my_session"). 2. After setting the session name, call session_start() to start the session. Configuring session names can avoid session data conflicts between multiple applications and enhance security, but pay attention to the uniqueness, security, length and setting timing of session names.

The session ID should be regenerated regularly at login, before sensitive operations, and every 30 minutes. 1. Regenerate the session ID when logging in to prevent session fixed attacks. 2. Regenerate before sensitive operations to improve safety. 3. Regular regeneration reduces long-term utilization risks, but the user experience needs to be weighed.

Setting session cookie parameters in PHP can be achieved through the session_set_cookie_params() function. 1) Use this function to set parameters, such as expiration time, path, domain name, security flag, etc.; 2) Call session_start() to make the parameters take effect; 3) Dynamically adjust parameters according to needs, such as user login status; 4) Pay attention to setting secure and httponly flags to improve security.

The main purpose of using sessions in PHP is to maintain the status of the user between different pages. 1) The session is started through the session_start() function, creating a unique session ID and storing it in the user cookie. 2) Session data is saved on the server, allowing data to be passed between different requests, such as login status and shopping cart content.

How to share a session between subdomains? Implemented by setting session cookies for common domain names. 1. Set the domain of the session cookie to .example.com on the server side. 2. Choose the appropriate session storage method, such as memory, database or distributed cache. 3. Pass the session ID through cookies, and the server retrieves and updates the session data based on the ID.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 English version
Recommended: Win version, supports code prompts!

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SublimeText3 Linux new version
SublimeText3 Linux latest version