My android advanced tour --> Android asynchronously loads Image Display and caches Images

Source: Internet
Author: User

Step 1: Create a project dataasyncload, as shown in

Step 2: Set the application UI

A. Main. xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><ListView      android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:id="@+id/listView"    /></LinearLayout>

B. listview_item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <ImageView         android:layout_width="42dp"        android:layout_height="42dp"        android:id="@+id/imageView"          />    <TextView         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textSize="18sp"        android:textColor="#FFFFFF"        android:id="@+id/textView"                /></LinearLayout>

Step 3: write some helper classes CN. roco. Data. utilsmd5.java

package cn.roco.data.utils;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5 {public static String getMD5(String content) {try {MessageDigest digest = MessageDigest.getInstance("MD5");digest.update(content.getBytes());return getHashString(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}    private static String getHashString(MessageDigest digest) {        StringBuilder builder = new StringBuilder();        for (byte b : digest.digest()) {            builder.append(Integer.toHexString((b >> 4) & 0xf));            builder.append(Integer.toHexString(b & 0xf));        }        return builder.toString();    }}

Step 4: Write the app's JavaBean CN. roco. Data. domain. Contact. Java

package cn.roco.data.domain;public class Contact {private int id;private String name;private String image;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getImage() {return image;}public void setImage(String image) {this.image = image;}public Contact(int id, String name, String image) {this.id = id;this.name = name;this.image = image;}public Contact(){}}

Step 5: Write an application's service layer to operate the JavaBean CN. roco. Data. Service. contactservice. Java

Package CN. roco. data. service; import Java. io. file; import Java. io. fileoutputstream; import Java. io. inputstream; import java.net. httpurlconnection; import java.net. URL; import Java. util. arraylist; import Java. util. list; import Org. xmlpull. v1.xmlpullparser; import android.net. uri; import android. util. XML; import CN. roco. data. domain. contact; import CN. roco. data. utils. MD5; public class contactservice {/*** get contact data ** @ Return * @ throws exception */public static list <contact> getcontacts () throws exception {string Path = "http: // 192.168.1.100: 8080/Hello/contact. XML "; httpurlconnection connection = (httpurlconnection) new URL (PATH ). openconnection (); connection. setconnecttimeout (5000); connection. setrequestmethod ("get"); If (connection. getresponsecode () == 200) {return parsexml (connection. getinputstream ();} retur N null;}/** convert XML to get data * the XML file on the server side is as follows ...... * <? XML version = "1.0" encoding = "UTF-8"?> <Contacts> <contact id = "1"> <Name> roco_1 </Name> <image src = "http: // 192.168.1.100: 8080/Hello/images/1.png"/> </contact> ....... </contacts> */Private Static list <contact> parsexml (inputstream) throws exception {list <contact> contacts = new arraylist <contact> (); contact = NULL; xmlpullparser pullparser = xml. newpullparser (); pullparser. setinput (inputstream, "UTF-8"); int event = pullparser. g Eteventtype (); While (event! = Xmlpullparser. end_document) {Switch (event) {Case xmlpullparser. start_tag: If ("Contact ". equals (pullparser. getname () {contact = new contact (); contact. setid (New INTEGER (pullparser. getattributevalue (0);} else if ("name ". equals (pullparser. getname () {contact. setname (pullparser. nexttext ();} else if ("image ". equals (pullparser. getname () {contact. setimage (pullparser. getattributevalue (0);} break; c ASE xmlpullparser. end_tag: If ("Contact ". equals (pullparser. getname () {contacts. add (contact); contact = NULL ;}event = pullparser. next ();} return contacts;}/*** get the network image. If the image exists in the cache, it is returned, otherwise, load the image from the network and cache it ** @ Param path * image path * @ return */public static URI getimage (string ImagePath, file cachedir) throws exception {// The cached file name is encrypted with MD5. File localfile = new file (cachedir, md5.getmd5 (ImagePath) + ImagePath. Substring (ImagePath. lastindexof (". "); If (localfile. exists () {return Uri. fromfile (localfile);} else {httpurlconnection connection = (httpurlconnection) new URL (ImagePath ). openconnection (); connection. setconnecttimeout (5000); connection. setrequestmethod ("get"); // cache the file if (connection. getresponsecode () == 200) {fileoutputstream outputstream = new fileoutputstream (localfile); inputstream = Connection. getinputstream (); byte [] buffer = new byte [1024]; int Len = 0; while (LEN = inputstream. Read (buffer ))! =-1) {outputstream. write (buffer, 0, Len);} inputstream. close (); outputstream. close (); Return Uri. fromfile (localfile) ;}} return NULL ;}}

Step 6: Write an adapter to update the data of listview CN. roco. Data. Adapter. contactadapter. Java

Package CN. roco. data. adapter; import Java. io. file; import Java. util. list; import CN. roco. data. r; import CN. roco. data. domain. contact; import CN. roco. data. service. contactservice; import android. content. context; import android.net. uri; import android. OS. asynctask; import android. OS. handler; import android. OS. message; import android. view. layoutinflater; import android. view. view; import android. view. viewgroup; import Android. widget. baseadapter; import android. widget. imageview; import android. widget. textview;/** adapter, used to update view */public class contactadapter extends baseadapter {private list <contact> data; private int listviewitem; private File Cache; /*** layoutinflater is similar to findviewbyid (). The difference is that layoutinflater is used to find and instantiate the XML layout file in the layout folder! * Findviewbyid () is used to find the widget controls (such as buttons and textview) in a specific XML file ). */Private layoutinflater; Public contactadapter (context, list <contact> data, int listviewitem, File Cache) {This. data = data; this. listviewitem = listviewitem; this. cache = cache; this. layoutinflater = (layoutinflater) context. getsystemservice (context. layout_inflater_service); // get the view defined in XML. *** getsystemservice () is an important API for Android. It is a method of activity, * obtain the corresponding object based on the input name, and then convert it to a phase Target of service. The following describes the system services. * The object returned by the input name indicates that the window program layout_inflater_service layoutinflater opened by window_service windowmanager is used to retrieve the view activity_service activitymanager defined in XML to manage the system status of the application. alarm_service alarmmanager alarm service notification_service icationicationmanager service keyguard_service keyguardmanager service location_service locationmanager service in the status bar, for example, the GPS search_service searchmanager search service vebrator_ser Vice vebrator mobile phone vibration service connectivity_service connectivity Network Connection Service wifi_service wifimanager Wi-Fi service telephony_service teleponymanager Telephone Service */}/** get the total number of data */@ overridepublic int getcount () {return data. size ();}/** obtain the data in the Set Based on the Data Index */@ overridepublic object getitem (INT position) {return data. get (position) ;}@ overridepublic long getitemid (INT position) {return position ;}@ overridepublic view getview (INT P Osition, view convertview, viewgroup parent) {imageview = NULL; textview = NULL; If (convertview = NULL) {convertview = layoutinflater. inflate (listviewitem, null); imageview = (imageview) convertview. findviewbyid (R. id. imageview); textview = (textview) convertview. findviewbyid (R. id. textview); convertview. settag (New datawrapper (imageview, textview); // wrap the content for future use} else {datawrapper Datawrapper = (datawrapper) convertview. gettag (); // extract the packaging class // obtain the data from the packaging class imageview = datawrapper. getimageview (); textview = datawrapper. gettextview ();} Contact contact = data. get (position); textview. settext (contact. getname ();/** asynchronously load image files */asynchimageload (imageview, contact. getimage (); Return convertview;}/* // This method creates many threads and consumes a lot of resources. Private void asynchimageload (final imageview, final string ImagePath) {final ha Ndler handler = new handler () {@ overridepublic void handlemessage (Message MSG) {// URI uri = (URI) msg. OBJ; If (Uri! = NULL & imageview! = NULL) {imageview. setimageuri (URI) ;}}; runnable = new runnable () {@ overridepublic void run () {try {URI uri = contactservice. getimage (ImagePath, cache); handler. sendmessage (handler. obtainmessage (10, Uri);} catch (exception e) {e. printstacktrace () ;}}; new thread (runnable ). start ();} * // ** asynchronously load the image file */private void asynchimageload (imageview, string ImagePath) {asycimagetask = new Sycimagetask(imageviewath ;asycimagetask.exe cute (ImagePath);}/*** use asynctask to improve performance * optional methods: 1, onprogressupdate (progress ...) You can use the progress bar to increase user experience. This method is executed in the main thread. The user displays the progress of the task execution. 2. onpreexecute () is the interface when the latest user calls excute. When this method is called before the task is executed, the Progress dialog box is displayed here. 3. What to do when the oncancelled () user calls cancel. Asynctask <Params, progress, result> asysctask defines three generic types: Params, progress, and result. 1. input parameters for Params startup task execution, such as HTTP request URL 2, percentage of progress background task execution 3, and final result returned by result background task execution, such as string, for example, the list that I need. When using the asynctask class, the following rules are observed: 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 onpfreexecute (), onpostexecute (result) doinbackground (Params ...), Onprogressupdate (progress ...) 4. The task can only be executed once. Otherwise, exceptions may occur during multiple calls. The entire call process of asynctask starts from the execute method, once the execute method is called in the main thread, you can use the onpreexecute method, which is a preprocessing method. For example, you can start a progress box here, you can also use the onprogressupdate method to display the progress bar to improve the user experience. Finally, the onpostexecute method is equivalent to handler's UI processing method, here, you can use the result processing UI in doinbackground. This method is executed in the main thread. The task execution result is returned as a parameter of this method */private final class asycimagetask extends asynctask <string, integer, Uri> {private imageview; public asycimagetask (imageview) {This. imageview = imageview;}/*** run in the background. Time-consuming operations can be stored here. Note that you cannot directly operate the UI here. This method is executed in the background thread to complete the main work of the task, usually takes a long time. You can call public progress (progress…) during execution ...) To update the task progress. * // @ Overrideprotected URI doinbackground (string... params) {// run try {return contactservice in the Child thread. getimage (Params [0], cache);} catch (exception e) {e. printstacktrace ();} return NULL;}/*** is equivalent to handler's way of processing the UI. Here, you can use the result obtained in doinbackground * to process the UI. This method is executed in the main thread, and the task execution result is returned as a parameter of this method. * // @ Overrideprotected void onpostexecute (URI result) {// run in the main thread if (result! = NULL & imageview! = NULL) {imageview. setimageuri (result) ;}}/ ** data packaging class */private final class datawrapper {private imageview; private textview; Public imageview getimageview () {return imageview ;} public textview gettextview () {return textview;} public datawrapper (imageview, textview) {This. imageview = imageview; this. textview = textview ;}}}

Step 7: The application's main program CN. roco. Data. mainactivity. Java

Package CN. roco. data; import Java. io. file; import Java. util. list; import CN. roco. data. adapter. contactadapter; import CN. roco. data. domain. contact; import CN. roco. data. service. contactservice; import android. app. activity; import android. OS. bundle; import android. OS. environment; import android. OS. handler; import android. widget. listview; public class mainactivity extends activity {private listview;/** cache file */Private File Cache;/** receives and processes messages. This handler runs with the current main thread * uses anonymous internal classes to rewrite handlermessage () in the handler () method */handler = new handler () {// accept public void handlemessage (Android. OS. message MSG) {// set the adapter to use the adapter to update viewlistview. setadapter (New contactadapter (mainactivity. this, (list <contact>) MSG. OBJ, R. layout. listview_item, cache) ;};@overridepublic void oncreate (bundle savedinstancestate) {super. oncr Eate (savedinstancestate); setcontentview (R. layout. main); listview = (listview) This. findviewbyid (R. id. listview);/** generate the cache directory in the SD card */cache = new file (environment. getexternalstoragedirectory (), "cache");/** create a new */If (! Cache. exists () cache. mkdir (); New thread (New runnable () {@ overridepublic void run () {try {// obtain the contact data list <contact> DATA = contactservice. getcontacts (); // sends a message to handler to update uihandler. sendmessage (handler. obtainmessage (22, data);} catch (exception e) {e. printstacktrace ();}}}). start () ;}@ overrideprotected void ondestroy () {/** clear cache file */For (File file: cache. listfiles () {file. delete ();} cache. delete (); super. ondestroy ();}}

Step 8: androidmanifest. xml

<? XML version = "1.0" encoding = "UTF-8"?> <Manifest xmlns: Android = "http://schemas.android.com/apk/res/android" package = "CN. roco. data "Android: versioncode =" 1 "Android: versionname =" 1.0 "> <uses-SDK Android: minsdkversion =" 8 "/> <! -- Access Internet permissions --> <uses-Permission Android: Name = "android. Permission. Internet"/> <! -- Create and delete file permissions on the SD card --> <uses-Permission Android: Name = "android. Permission. mount_unmount_filesystems"/> <! -- Write data permission to the SD card --> <uses-Permission Android: Name = "android. permission. write_external_storage "/> <application Android: icon =" @ drawable/icon "Android: Label =" @ string/app_name "> <activity Android: Name = ". mainactivity "Android: Label =" @ string/app_name "> <intent-filter> <action Android: Name =" android. intent. action. main "/> <category Android: Name =" android. intent. category. launcher "/> </intent-filter> </activity> </Application> </manifest>

Step 9: Write the server code, mainly a contact. xml file.

<?xml version="1.0" encoding="UTF-8"?><contacts><contact id="1"><name>Roco_1</name><image src="http://192.168.1.100:8080/Hello/images/1.png" /></contact><contact id="2"><name>Roco_2</name><image src="http://192.168.1.100:8080/Hello/images/2.png" /></contact><contact id="3"><name>Roco_3</name><image src="http://192.168.1.100:8080/Hello/images/3.png" /></contact><contact id="4"><name>Roco_4</name><image src="http://192.168.1.100:8080/Hello/images/4.png" /></contact><contact id="5"><name>Roco_5</name><image src="http://192.168.1.100:8080/Hello/images/5.png" /></contact><contact id="6"><name>Roco_6</name><image src="http://192.168.1.100:8080/Hello/images/6.png" /></contact><contact id="7"><name>Roco_7</name><image src="http://192.168.1.100:8080/Hello/images/7.png" /></contact><contact id="8"><name>Roco_8</name><image src="http://192.168.1.100:8080/Hello/images/8.png" /></contact><contact id="9"><name>Roco_9</name><image src="http://192.168.1.100:8080/Hello/images/9.png" /></contact><contact id="10"><name>Roco_10</name><image src="http://192.168.1.100:8080/Hello/images/10.png" /></contact><contact id="11"><name>Roco_11</name><image src="http://192.168.1.100:8080/Hello/images/11.png" /></contact><contact id="12"><name>Roco_12</name><image src="http://192.168.1.100:8080/Hello/images/12.png" /></contact><contact id="13"><name>Roco_13</name><image src="http://192.168.1.100:8080/Hello/images/13.png" /></contact><contact id="14"><name>Roco_14</name><image src="http://192.168.1.100:8080/Hello/images/14.png" /></contact><contact id="15"><name>Roco_15</name><image src="http://192.168.1.100:8080/Hello/images/15.png" /></contact><contact id="16"><name>Roco_16</name><image src="http://192.168.1.100:8080/Hello/images/16.png" /></contact><contact id="17"><name>Roco_17</name><image src="http://192.168.1.100:8080/Hello/images/17.png" /></contact><contact id="18"><name>Roco_18</name><image src="http://192.168.1.100:8080/Hello/images/18.png" /></contact><contact id="19"><name>Roco_19</name><image src="http://192.168.1.100:8080/Hello/images/19.png" /></contact><contact id="20"><name>Roco_20</name><image src="http://192.168.1.100:8080/Hello/images/20.png" /></contact></contacts>

And put some images in the images directory.

Step 10: deploy the project to the simulator for running:

Cache files are generated on the SD card.

When the application exits, the cached file is deleted.

With cached files, you can read the image files in the cache even if the application does not exit.

========================================================== ========================================================== ============================

Author: Ouyang Peng: Welcome to repost. sharing with others is the source of progress!

Reprinted Please retain the original address: http://blog.csdn.net/ouyang_peng

========================================================== ========================================================== ============================

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.