The service of Android system programming introduction series goes hand in hand with multi-threaded tasks

In the previous article, I had a preliminary understanding of the service service, one of the four components of the Android system, which can perform time-consuming operation tasks without user interaction. However, including the previous series of articles on the interface, the life cycle method is called back by the system in the main thread. If the time-consuming operation is directly executed in the life cycle method, it may also trigger the anr exception of the system to the application due to no response within 5S of the main thread. In order to solve this problem, we need to use multi-threaded development to execute time-consuming tasks, and return the results to the main thread after the task execution.

The new task class needs to implement the java.lang.runnable interface to handle the tasks to be operated in the implemented run () method.

There are three main ways to start new tasks in development. One is to directly create the most basic thread class to manage and execute time-consuming tasks separately; The second is to create a thread pool composed of a pile of threads, put time-consuming tasks into execution, and the rest are managed by the thread pool; The third is to use mature concurrent libraries. The way to create and start tasks according to different concurrent libraries will not be limited to runnable instances. In addition, before Android R, that is, api30, you can also use android.os.asynctask to create asynchronous tasks, but this method has been abandoned after api30, so it is not recommended. The following will briefly introduce the above three mainstream methods.

The thread (runnable target) construction method is usually used to create sub threads, and the parameter target is used as the task object to be executed. Then, call the start () method of the child thread object at the position where the task needs to be executed to start and run the thread. Because the created thread is a component that relies on an interface activity or service, when the lifecycle method of the component is destroyed, the child thread created will be destroyed. Therefore, the subthread must be called interrupt () before it is destroyed to run and release the resources it occupies, so as to prevent memory leakage.

Through a series of static methods such as newcachedthreadpool() of the thread pool management class java.util.concurrent.executors, you can directly create the thread pool class instantiation object defined by the java.util.concurrent.executor interface. Then, call the execute (runnable command) method of the thread pool object at the location where the task needs to be executed to execute the task once. The advantage of thread pool class is that when the life cycle method of the component is destroyed, the thread pool and its threads will be forcibly destroyed without manual management.

With regard to the multithreading development of Android system, there are many mature concurrency libraries that can be used directly, including rxjava based on Java and kotlin based collaboration. However, their underlying principles are similar to the above. How to use the existing multithreading development library will be described in detail in subsequent articles.

Because different tasks run in different threads, the communication between tasks is actually the communication between threads. This is mainly implemented through the android.os.handler class. When it comes to communication, it is the process of one party sending content and the other party receiving content. The Android system encapsulates the content to be communicated into android.os.message class, in which int arg1 and int arg2 attributes store simple numerical content, object obj attribute stores objects of any type, and int what attribute can mark and distinguish different message types.

In the thread that needs to process the communication content, create the handler instantiation object. You can use the handler (looper looper) constructor or the createsync (looper looper) static method to create an instantiated object that handles arbitrary content. The parameter looper marks which thread the processing operation in the current handler object is on. If it is the main thread, you can use the looper. Getmainlooper() static method to obtain the android.os.looper object. If it is a child thread, you can use the looper. Myloop() static method in the run() method of the child thread to obtain the looper object of the current thread.

Or use the handler (looper, looper, handler. Callback) construction method or createsync (looper, looper, handler. Callback) static method to create an instantiated object that needs to receive message processing. The parameter looper also marks which thread the processing operation in the current handler object is in. The parameter callback is an instantiated object implemented by the android.os.handler.callback interface, in which the implemented handlemessage (message MSG) method can receive and process the communication results. The MSG parameter here is the content of the received message.

If the looper object is obtained through the looper. Myloop() static method, that is, the communication results are processed in the sub thread, two methods should be called before and after the handler object is created. Before initializing the handler object above, you must first call the looper. Prepare() static method in the child thread to initialize the looper object, so as to ensure that the object obtained when calling the looper. Myloop() method is not empty. And after initializing the handler object, the loop. Loop () static method must be called in time in the current child thread to prepare the message queue for use by the current child thread.

In the thread that needs to send communication content, you need to first receive the handler instantiation object created above.

When switching the processing position of the thread, call the post (runnable R) series methods of the handler object. The parameter r is the runnable task object to be processed in the thread where the handler object is located.

Or call the obtainmessage() series methods of the handler object at the location where the message needs to be sent to obtain the idle available message object, and assign the content of the message body to be sent to different properties of the message object. Finally, call the SendMessage (message MSG) series methods of the handler object to send the message body to the message object.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>