Android thread model: When an Android Application runs, a main thread of the UI starts. This is a very important thread that distributes events to corresponding controls, this includes screen plotting events, which are also threads for user interaction with Android controls. For example, when you input text in edittext on the screen, the UI thread will distribute the event to
Edittext, which sends an update (invalidate) request to the event queue immediately. The UI thread will remove this request from the event queue and notify edittext to redraw itself on the screen.
This single-thread model will make the Android Application inferior in performance. If you perform some time-consuming operations in this single-thread, such as accessing the database or downloading images from the network, the entire user interface is blocked. For example:
Bitmap b = loadImageFromNetwork();
This operation is very time-consuming. In this case, you will find that the interface is frozen and Android does not respond after 5 seconds in the system, and an error of disabling or waiting will be displayed.
Maybe we can use a new thread to solve it.
new Thread(new Runnable() { public void run() { Bitmap b = loadImageFromNetwork(); mImageView.setImageBitmap( b ); } }).start();
But this will cause some very imperceptible errors, because we know that the UI thread is NOT thread-safe. Of course there are many ways to deal with this problem:
Android provides several methods to access the UI thread in other threads.
• Activity. runonuithread (runnable)
• View. Post (runnable)
• View. postdelayed (runnable, long)
• Hanlder
new Thread( new Runnable() { public void run() { final Bitmap b = loadImageFromNetwork(); mImageView.post( new Runnable() { mImageView.setImageBitmap( b ); }); } }).start();
This method is cumbersome. It also gets worse when you need to implement complicated operations and update the UI frequently. To solve this problem, Android provides a tool class: asynctask, which makes it easier to create long-running tasks that need to interact with the user interface.
For example, attach a network image:
Ublic class canvasimagetask extends asynctask <imageview, void, bitmap> {private imageview gview; protected bitmap doinbackground (imageview... views) {bitmap BMP = NULL; imageview view = views [0]; // obtain and render the Image Based on iconurl. The iconurl URL is placed in the view tag. If (view. gettag ()! = NULL) {try {URL url = new URL (view. gettag (). tostring (); httpurlconnection conn = (httpurlconnection) URL. openconnection (); Conn. setdoinput (true); Conn. connect (); inputstream stream = Conn. getinputstream (); BMP = bitmapfactory. decodestream (Stream); stream. close ();} catch (exception e) {log. V ("IMG", E. getmessage (); return NULL ;}} this. gview = view; return BMP;} protected void onpostexecute (Bitmap BM) {If (BM! = NULL) {This. gview. setimagebitmap (BM); this. gview = NULL ;}} call if (! IMG. isdrawingcacheenabled () |! Holder. image. gettag (). equals (imgpath) {IMG. setimageresource (R. drawable. icon_app); IMG. settag (imgpath); try {New canvasimagetask(.exe cute (IMG); IMG. setdrawingcacheenabled (true);} catch (exception e) {log. E ("error", "rejectedexecutionexception in content_img:" + imgpath );
In this way, the asynchronous thread is used for image loading without blocking. We can also use callback for callback after image loading.
Public class canvasimagetaskcall extends asynctask <imageview, void, bitmap> implements callback {private imageview gview; protected bitmap doinbackground (imageview... views) {bitmap BMP = NULL; imageview view = views [0]; // obtain and render the Image Based on iconurl. The iconurl URL is placed in the view tag. If (view. gettag ()! = NULL) {try {URL url = new URL (view. gettag (). tostring (); httpurlconnection conn = (httpurlconnection) URL. openconnection (); Conn. setdoinput (true); Conn. connect (); inputstream stream = Conn. getinputstream (); BMP = bitmapfactory. decodestream (Stream); stream. close ();} catch (exception e) {e. printstacktrace (); log. V ("IMG", E. getmessage (); message MSG = new message (); MSG. what = 0; handlemessage (M SG); return NULL ;}} this. gview = view; return BMP;} protected void onpostexecute (Bitmap BM) {If (BM! = NULL) {This. gview. setimagebitmap (BM); this. gview. settag (BM); this. gview = NULL; message MSG = new message (); MSG. what = 1; handlemessage (MSG);} public Boolean handlemessage (Message MSG) {// todo auto-generated method stub return false ;}}
Directly call in Activity
New canvasimagetaskcall () {@ override public Boolean handlemessage (Message MSG) {Switch (MSG. what) {Case 0: log. I ("test", "image loading failed"); break; Case 1: log. I ("test", "image loaded successfully"); break; default: break;} savebutton. settextcolor (color. white); savebutton. setclickable (true); bitmap = (Bitmap) imageview. gettag (); return Super. handlemessage (MSG);} cmd.exe cute (IMG );