When developing Android applications, you must follow the single-thread model principle: Android UI operations are not thread-safe and must be executed in the UI thread. In a single-threaded model, you must always remember the following two rules:
1. Do not block the UI thread
2. Make sure to only access the android UI toolkit in the UI thread
When a program is started for the first time, Android starts a corresponding main thread at the same time. The main thread is mainly responsible for processing UI-related events, such as user key events, the user contacts screen events and Screen Drawing events, and distributes related events to corresponding components for processing. Therefore, the main thread is often called the UI thread.
For example, you can obtain a webpage from the Internet and display its source code in a textview. This kind of program involving network operations generally requires a thread to complete network access. However, after obtaining the page source code, yes. textview cannot be called directly in the Network Operation thread. settext. because other threads cannot directly access the main UI thread Member
Android provides several methods to access the UI thread in other threads.
Activity. runonuithread (runnable)
View. Post (runnable)
View. postdelayed (runnable, long)
Hanlder
These classes or methods also make your code complex and hard to understand. However, when you need to implement complex operations and frequently update the UI, this will become worse.
To solve this problem, Android 1.5 provides a tool class: asynctask, which makes it easier to create long-running tasks that need to interact with the user interface. It can be implemented without using threads and handler.
Asynctask is an abstract class. asynctask defines three generic types: Params, SS, and result.
Input parameters for Params startup task execution, such as the URL of the HTTP request.
Percentage of progress background tasks.
Result: The result returned when the task is executed in the background, such as string.
The execution of asynctask is divided into four steps. Each step corresponds to a callback method, which should not be called by the application. All developers need to do is implement these methods.
1) subclass asynctask
2) implement one or more of the following methods defined in asynctask
Onpreexecute (), this method will be called by the UI thread before the actual background operation is executed. You can make some preparations in this method, such as displaying a progress bar on the interface.
Doinbackground (Params...) will be executed immediately after the onpreexecute method is executed. This method runs in the background thread. Here, we will primarily perform those time-consuming background computing tasks. You can call publishprogress to update the real-time task progress. This method is an abstract method and must be implemented by sub-classes.
Onprogressupdate (Progress...), after the publishprogress method is called, UI thread will call this method to display the progress of the task on the interface, for example, display through a progress bar.
Onpostexecute (result). After doinbackground is executed, the onpostexecute method will be called by the UI thread, and the background computing result will be passed to the UI thread through this method.
To correctly use the asynctask class, the following guidelines must be followed:
1) The task instance must be created in the UI thread.
2) The execute method must be called in the UI thread.
3) do not manually call the onpreexecute (), onpostexecute (result), doinbackground (Params...), onprogressupdate (Progress...) methods.
4) The task can only be executed once. Otherwise, exceptions may occur during multiple calls.
Obtain a webpage from the Internet and display its source code in a textview.
Java code
- Package test. List;
- Import java. Io. bytearrayoutputstream;
- Import java. Io. inputstream;
- Import java. util. arraylist;
- Import org. Apache. http. httpentity;
- Import org. Apache. http. httpresponse;
- Import org. Apache. http. Client. httpclient;
- Import org. Apache. http. Client. Methods. httpget;
- Import org. Apache. http. impl. Client. defaulthttpclient;
- Import Android. App. activity;
- Import Android. App. progressdialog;
- Import Android. content. context;
- Import Android. content. dialoginterface;
- Import Android. OS. asynctask;
- Import Android. OS. Bundle;
- Import Android. OS. Handler;
- Import Android. OS. message;
- Import Android. View. view;
- Import Android. widget. Button;
- Import Android. widget. edittext;
- Import Android. widget. textview;
- Public class networkactivity extends activity {
- Private textview message;
- Private button open;
- Private edittext URL;
- @ Override
- Public void oncreate (bundle savedinstancestate ){
- Super. oncreate (savedinstancestate );
- Setcontentview (R. layout. Network );
- Message = (textview) findviewbyid (R. Id. Message );
- Url = (edittext) findviewbyid (R. Id. url );
- Open = (button) findviewbyid (R. Id. Open );
- Open. setonclicklistener (New View. onclicklistener (){
- Public void onclick (view arg0 ){
- Connect ();
- }
- });
- }
- Private void connect (){
- Pagetask task = new pagetask (this );
- Task.exe cute (URL. gettext (). tostring ());
- }
- Class pagetask extends asynctask <string, integer, string> {
- // Variable length input parameter, which corresponds to asynctask. exucute ()
- Progressdialog pdialog;
- Public pagetask (context ){
- Pdialog = new progressdialog (context, 0 );
- Pdialog. setbutton ("cancel", new dialoginterface. onclicklistener (){
- Public void onclick (dialoginterface dialog, int I ){
- Dialog. Cancel ();
- }
- });
- Pdialog. setoncancellistener (New dialoginterface. oncancellistener (){
- Public void oncancel (dialoginterface DIALOG ){
- Finish ();
- }
- });
- Pdialog. setcancelable (true );
- Pdialog. setmax (100 );
- Pdialog. setprogressstyle (progressdialog. style_horizontal );
- Pdialog. Show ();
- }
- @ Override
- Protected string doinbackground (string... Params ){
- Try {
- Httpclient client = new defaulthttpclient ();
- // Params [0] indicates the URL of the connection.
- Httpget = new httpget (Params [0]);
- Httpresponse response = client.exe cute (get );
- Httpentity entity = response. getentity ();
- Long length = entity. getcontentlength ();
- Inputstream is = entity. getcontent ();
- String S = NULL;
- If (is! = NULL ){
- Bytearrayoutputstream baos = new bytearrayoutputstream ();
- Byte [] Buf = new byte [1, 128];
- Int CH =-1;
- Int COUNT = 0;
- While (CH = is. Read (BUF ))! =-1 ){
- Baos. Write (BUF, 0, CH );
- Count + = CH;
- If (length> 0 ){
- // If you know the response length, call publishprogress () to update the progress.
- Publishprogress (INT) (count/(float) length) * 100 ));
- }
- // Sleep the thread for 100 ms
- Thread. Sleep (100 );
- }
- S = new string (baos. tobytearray ());}
- // Return results
- Return S;
- } Catch (exception e ){
- E. printstacktrace ();
- }
- Return NULL;
- }
- @ Override
- Protected void oncancelled (){
- Super. oncancelled ();
- }
- @ Override
- Protected void onpostexecute (string result ){
- // Return the HTML page content
- Message. settext (result );
- Pdialog. Dismiss ();
- }
- @ Override
- Protected void onpreexecute (){
- // Start the task. A dialog box is displayed here, which is simple.
- Message. settext (R. String. task_started );
- }
- @ Override
- Protected void onprogressupdate (integer... values ){
- // Update Progress
- System. Out. println ("" + values [0]);
- Message. settext ("" + values [0]);
- Pdialog. setprogress (Values [0]);
- }
- }
- }