Android message mechanism, asynchronous and Multithreading

Source: Internet
Author: User

Since the broad application of the framework, we do not have to deal with naked mobile phone operating system APIs and do repetitive, complex, and meaningless things. However, there is no free lunch in the world. We still need to learn how to use different frameworks efficiently and correctly. Many methods to deal with a specific problem are different in different frameworks. Today, we mainly learn how to use andorid framework.

In Android, the lower layer is the kernel of Linux, but the framework made by the upper layer of Java makes all the encapsulation airtight. Taking message processing as an example, in MFC, we can use pretranslatemessage and other Dongdong to freely process messages. in C #, the boss of Anders hejlsberg said, he opened a "life-saving window" for us to the bottom layer, but unfortunately, in Android, the window was closed (at least I didn't find it now ...).

In Android, you want to process some messages (such as keydown ...), you must find some overload functions provided by activity for you (such as onkeydown ...) or a variety of listener (such as onkeydownlistner ...). The advantage of doing so is obvious. The more freedom there will be the more danger and the more obscure it will be. It's easy to use and save your mind, this is what a well-designed framework should offer. For my current project, I don't have any BT requirements that I can't do under the current API. Google's design MS is still very nice.

However, the world is cruel. Sometimes we still need mechanisms to provide message distribution and processing, because some jobs cannot be processed synchronously by direct calls, at the same time, it cannot be achieved through embedded message distribution and interface settings in the activity, such as scheduled touch of events, asynchronous processing of cyclic events, and high time-consuming work. In Android, it provides some interesting ways to do this. (sorry, I don't know much about it. I have never seen similar methods, I have seen it before. OS. handler class. This class accepts a logoff parameter. As the name suggests, it is a encapsulated class that represents a message loop. By default, Handler accepts the message loop instances in the current thread, that is, a message loop can be distributed by multiple objects in the current thread for processing (in the UI thread, the system already has an activity to process. You can start several handler to process it ...). After instantiating a handlerinstance, you can send messages through sendmessage and other message sending mechanisms, and send messages by reloading handlemessage and other functions. But! The handlerinstance can receive messages only through handlerinstance. the message constructed by the obtainmessage (this statement is not accurate. You can also manually create a message and configure it to be handled by the handlerinstance. I didn't follow in to analyze its identification mechanism, if you are interested, play with it. ^_^ ). That is to say, A, B, C, and D can all process message distribution in the same thread, but each of them can only process its own message, this obliterates the possibility that B wants to secretly enter the territory of A, and the greater the number of agents, the more possible it is to do some non-copy tasks (theoretically, B may pretend that the messages are the same as those of a's family, I did not try to challenge Google's IQ. If you have BT requirements, I will study it myself. ^_^ ). In this way, not only flexibility is taken into account, but security is also ensured, and it will be simple to use. I am the owner of my website and do not need to be hurt or innocent, it's a pleasure to have a left-right hug...

Obviously, message senders are not limited to their own threads. No one can only perform scheduled, delayed, and other things. During handler instantiation, logoff can be any thread. Any thread can sendmessage as long as there is a handler pointer (this construction method is also very interesting, you can construct handler by passing the Logoff of line B in thread A, or in thread B, which brings a huge variable to the memory management method ...). However, a rule must not be broken, that is, a non-UI thread cannot touch the UI class. There are many solutions on different platforms (if you have more than one interest, you can take a look at one I wrote a long time ago, no Sb, no money ). I specifically followed the asyncqueryhandler class in Android to learn about Google's official solutions.

Asyncqueryhandler is a subclass of handler. As mentioned in the document, if you are dealing with contentprovider-related content, you do not need to define a set of things, but you can simply use async. I want to refer to the asyncqueryhandler class. This class is a typical template class. It provides a good interface for adding, deleting, modifying, and querying contentprovider, provides a solution architecture, final some methods, and void some methods. Some methods are instantiated through derivation (not every contentprovider process requires adding, deleting, modifying, and querying all the methods. I think this is also the reason why this class is left empty by default, rather than abstracting some methods ), to achieve this goal. Internally, this class hides the details of multi-thread processing. When you use it, you will feel very convenient. Take query as an example. You can use this method:

// Define a handler and use an anonymous class to process only query. Therefore, only the onquerycomplete function is rewritten:
Queryhandler = new asyncqueryhandler (this. getcontentresolver () {// The input is a contentresolver instance, so the handler class must be instantiated after oncreate
@ Override
Protected void onquerycomplete (INT token, object cookie, cursor ){
// Here you can get a cursor and the additional tokens and cookies you pass in.
// This method is in the current thread (if the default logoff is passed in), the UI information can be set freely.
}
};

 

You only need to call the startquery (INT token, object cookie, contenturi Uri, string [] projection, string selection, string [] selectionargs, string sortorder) function:
Queryhandler. startquery (token, Cookie, Uri, projection, selection, selectionargs, sortby );

It can be seen how simple this class is to be used (its implementation is not very easy, because I tried to create a wheel * _ *), which is countless times simpler than using handler directly. But what made me feel lonely is that I don't know whether no one is doing asynchronous contentprovider access, or whether this class is too mentally retarded (I have been exploring this method for a long time, is it true that I am so weak @ _ @), or everyone has their own tips. From the SDK to the Internet, there is no usage instructions on this class. And I happened to sadly find that this class actually has many problems. For example, if he eats an exception, if there is a mistake, it simply returns a null pointer (this cannot blame him, you can see here ...); when you pass in a null contentresolver, there is no exception, but inexplicably discard all the messages, so that you are stuck in a hard wait and don't know why. What's more furious is that, there is a bug in token passing (is it true that I am not using it? & _ &). The token passed in from startxx is changed to 1 in onxxcomplete, the document clearly states that two items are one thing (my solution is to use cookies as tokens and this will not lose *_*). However, I have no plans to abandon it for the moment. Although no one cares about it, although there are a bunch of problems, although I have made a new wheel on the map, in order to save some boring work, I decided to cheat myself...

It is still a habit to run the question. In fact, I want to talk about its multi-thread asynchronous processing solution strategy through countless debugger follow-up on this class. The basic policy is as follows:

1. when you instantiate an asyncqueryhandler class (including its subclass ...), it constructs a thread in one piece (detailed later ...), this thread will build a message loop.
2. Get the pointer to the message loop and use it as a parameter to instantiate another handler class, which is an internal class. So far, there are two threads, each having a handler to process messages.
3. When onxxx is called, the request is encapsulated into an internal parameter class in the xxx function, which serves as the parameter of the message and sends the message to another thread.
4. In the handler of the thread, accept the message, analyze the input parameters, perform the xxx operation with the contentresolver passed in during initialization, and return the cursor or other return values.
5. Construct a message, bind the returned values and other related content to the message, and send the message back to the main thread.
6. the handlemessage method of the default asyncqueryhandler class of the main thread (which can be customized, but because it is an internal class, it is basically meaningless ...) the message is analyzed and forwarded to the corresponding onxxxcomplete method.
7. The onxxxcomplete method rewritten by the user starts to work.

This is what it has done secretly. It is basically easy to understand. The only thing I'm curious about is its thread management method. I guess it is a single-piece mode. The instantiation of the first asyncqueryhandler will lead to the creation of a thread. From then on, this thread becomes an immortal male. All contentresolver-related work is completed by this thread in a unified manner. I personally think this solution is awesome. The life cycle of this thread is hard to estimate, and when you have a contentprovider request, it is not excessive to judge that you will perform more similar operations. Even if it is wrong, the cost is only an endless thread (same as the process ...), in exchange for simple lifecycle management and numerous savings on thread Life and Death overhead. At the same time, another very important issue involves data synchronization in a single piece. Each class has its own handler class, which does not interfere with each other. distribution can be performed separately. When there are multiple data requests, the same contentresolver may have very few operations, which avoids blocking. All in all, this solution is perfectly compatible with the overall Android design.

We recommend that you simulate a set of non-contentprovider operations that require asynchronous multi-thread execution. Of course, the specific situation is analyzed, it is hard to learn Marxism-Leninism... The message mechanism of Android, asynchronous and multithreading, is actually not complicated, as long as you are interested, you can learn.

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.