Android Programming Learning method for asynchronous loading of pictures _android

Source: Internet
Author: User
Tags thread class

This article is an example of how Android programming learns to load pictures asynchronously. Share to everyone for your reference, specific as follows:

The most recent challenge in Android development is to load a picture memory overflow. I developed a news application, the application of a large number of pictures, an interface may have hundreds of pictures. Developers of Android applications may be more or less hit the loading picture memory overflow problem, in general, loading a large image will lead to memory overflow, the same, loading more than one picture memory overflow probability is very high.

Make a list of the general practices found on the Web:

1. Use bitmapfactory.options to compress pictures
2. Optimize the GetView method in the adapter of loading pictures so as to occupy as little memory as possible
3. Use the asynchronous loading of the picture, so that the picture after the page load slowly loaded in.

1, 2 steps is necessary to do enough work, but for a large number of pictures of the list still can not solve the problem of memory overflow, the use of asynchronous loading of pictures in order to effectively solve the picture load memory overflow problem.

The effect of the test is shown below:

Here I post the main code and share it with you.

1, first is the code of the mainactivity and Activity_main.xml layout files.

(1), mainactivity code is as follows:

Package net.loonggg.test; 
Import java.util.List; 
Import Net.loonggg.adapter.MyAdapter; 
Import Net.loonggg.bean.Menu; 
Import Net.loonggg.util.HttpUtil; 
Import Net.loonggg.util.Utils; 
Import android.app.Activity; 
Import Android.app.ProgressDialog; 
Import Android.os.AsyncTask; 
Import Android.os.Bundle; 
Import Android.view.Window; 
Import Android.widget.ListView; 
 public class Mainactivity extends activity {private ListView LV; 
 Private Myadapter adapter; 
 Private ProgressDialog PD; 
  @Override protected void OnCreate (Bundle savedinstancestate) {requestwindowfeature (window.feature_no_title); 
  Super.oncreate (savedinstancestate); 
  Setcontentview (R.layout.activity_main); 
  LV = (ListView) Findviewbyid (r.id.lv); 
  PD = new ProgressDialog (this); 
  Pd.settitle ("Load Menu"); 
  Pd.setmessage ("Loading"); 
  adapter = new Myadapter (this); 
 New MyTask (). Execute ("1"); public class MyTask extends Asynctask<string, Void, list<menu>> {@Override protected VOID OnPreExecute () {super.onpreexecute (); 
  Pd.show (); 
   @Override protected void OnPostExecute (list<menu> result) {Super.onpostexecute (result); 
   Adapter.setdata (result); 
   Lv.setadapter (adapter); 
  Pd.dismiss (); } @Override protected list<menu> doinbackground (String ... params) {string menuliststr = Getlistdishesinfo 
   (Params[0]); 
  Return Utils.getinstance (). Parsemenusjson (MENULISTSTR); }} private String Getlistdishesinfo (string sortid) {//url string url = httputil.base_url + "Servlet/menuinfos 
  Ervlet?sortid= "+ SortID +" &flag=1 "; 
 The query returns the result return Httputil.querystringforpost (URL); 

 } 
}

(2), activity_main.xml layout files are as follows:

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" 
 xmlns:tools= "http:// Schemas.android.com/tools " 
 android:layout_width=" match_parent " 
 android:layout_height=" Match_parent " 
 android:background= "#ffffff" 
 android:orientation= "vertical" > 
 <listview 
  android:id= "@+id" /lv " 
  android:layout_width=" fill_parent " 
  android:layout_height=" wrap_content "> 
 </listview > 
</LinearLayout> 

2, this is the custom ListView adapter code:

Package net.loonggg.adapter; 
Import java.util.List; 
Import Net.loonggg.bean.Menu; 
Import NET.LOONGGG.TEST.R; 
Import Net.loonggg.util.ImageLoader; 
Import android.app.Activity; 
Import Android.content.Context; 
Import Android.view.LayoutInflater; 
Import Android.view.View; 
Import Android.view.ViewGroup; 
Import Android.widget.BaseAdapter; 
Import Android.widget.ImageView; 
Import Android.widget.TextView; 
 public class Myadapter extends Baseadapter {private list<menu> List; 
 private context; 
 activity of private activity; 
 Private Imageloader Imageloader; 
 Private Viewholder Viewholder; 
  Public Myadapter {this.context = context; 
  This.activity = (activity) context; 
 Imageloader = new Imageloader (context); 
 public void SetData (list<menu> list) {this.list = list; 
 @Override public int GetCount () {return list.size (); 
 @Override public Object getitem (int position) {return list.get (position); } @OverridE public long getitemid (int position) {return position; 
   @Override public View getview (int position, View Convertview, ViewGroup parent) {if (Convertview = null) { 
   Convertview = Layoutinflater.from (context). Inflate (R.layout.listview_item, NULL); 
   Viewholder = new Viewholder (); 
   Viewholder.tv = (TextView) Convertview.findviewbyid (R.ID.ITEM_TV); 
   VIEWHOLDER.IV = (ImageView) Convertview.findviewbyid (R.ID.ITEM_IV); 
  Convertview.settag (Viewholder); 
  else {Viewholder = (Viewholder) convertview.gettag (); 
  } viewHolder.tv.setText (List.get (position). Getdishes ()); 
  Imageloader.displayimage (List.get (position). Getpicpath (), activity, VIEWHOLDER.IV); 
 return convertview; 
  Private class Viewholder {private ImageView IV; 
 Private TextView TV; 

 } 
}

3, this is the most important part of the code, this is the asynchronous loading of a picture of a class, here I do not explain, the code is accompanied by annotations. The code is as follows:

Package net.loonggg.util; 
Import Java.io.File; 
Import Java.io.FileInputStream; 
Import java.io.FileNotFoundException; 
Import Java.io.FileOutputStream; 
Import Java.io.InputStream; 
Import Java.io.OutputStream; 
Import java.net.HttpURLConnection; 
Import Java.net.URL; 
Import java.util.Collections; 
Import Java.util.Map; 
Import Java.util.Stack; 
Import Java.util.WeakHashMap; 
Import NET.LOONGGG.TEST.R; 
Import android.app.Activity; 
Import Android.content.Context; 
Import Android.graphics.Bitmap; 
Import Android.graphics.BitmapFactory; 
Import Android.widget.ImageView;  /** * Asynchronous Loading Picture class * * @author LOONGGG * * */public class Imageloader {//cache private MemoryCache MemoryCache 
 = new MemoryCache (); 
 SD Card Cache private Filecache Filecache; 
 Private Picturesloader Pictureloaderthread = new Picturesloader (); 
 Private Picturesqueue Picturesqueue = new Picturesqueue (); Private Map<imageview, string> imageviews = collections. Synchronizedmap (New Weakhashmap< ImageView, string> ()); 
  Public Imageloader {//Set Thread priority pictureloaderthread.setpriority (THREAD.NORM_PRIORITY-1); 
 Filecache = new Filecache (context); 
 ////When the picture is not found, the default picture final int stub_id = r.drawable.stub; 
  public void displayimage (String url, activity activity, ImageView ImageView) {imageviews.put (ImageView, URL); 
  Bitmap Bitmap = memorycache.get (URL); 
  if (bitmap!= null) imageview.setimagebitmap (bitmap); 
   else {//If there is no picture in the phone's memory cache, call the task queue and set the default picture Queuephoto (URL, activity, imageview); 
  Imageview.setimageresource (stub_id); } private void Queuephoto (String url, activity activity, ImageView ImageView) {//This imageview may previously be used in other images. So there may be some old task queues. 
  We need to clear them off. 
  Picturesqueue.clean (ImageView); 
  Picturetoload p = new Picturetoload (URL, imageview); 
   Synchronized (picturesqueue.picturestoload) {PicturesQueue.picturesToLoad.push (P); 
  PicturesQueue.picturesToLoad.notifyAll (); //If this thread has not yet started, start thread if (PICTUreloaderthread.getstate () = = Thread.State.NEW) Pictureloaderthread.start (); /** * Bitmap * * @param URL for the corresponding picture based on URL * @return/private Bitmap getbitmap (String url) {File 
  f = filecache.getfile (URL); 
  Obtain Bitmap B = DecodeFile (f) from the SD card cache; 
  if (b!= null) return B; 
   Otherwise get try {Bitmap Bitmap = null from the network; 
   URL imageUrl = new URL (URL); 
   HttpURLConnection conn = (httpurlconnection) imageUrl. OpenConnection (); 
   Conn.setconnecttimeout (30000); 
   Conn.setreadtimeout (30000); 
   InputStream is = Conn.getinputstream (); 
   OutputStream OS = new FileOutputStream (f); 
   Write the picture to the SD card directory to Imageutil.copystream (is, OS); 
   Os.close (); 
   Bitmap = DecodeFile (f); 
  return bitmap; 
   catch (Exception ex) {ex.printstacktrace (); 
  return null; Decode image and zoom to reduce memory consumption private Bitmap decodefile (File f) {try {//decoding image dimensions bitmapfactory.options o = new 
   Bitmapfactory.options (); O.injustdecodebounds = tRue 
   Bitmapfactory.decodestream (new FileInputStream (f), NULL, O); Locate the correct scaling value. 
   This should be the power of 2. 
   Final int required_size = 70; 
   int width_tmp = o.outwidth, height_tmp = o.outheight; 
   int scale = 1; 
    while (true) {if (Width_tmp/2 < required_size | | | HEIGHT_TMP/2 < required_size) break; 
    Width_tmp/= 2; 
    Height_tmp/= 2; 
   Scale *= 2; //Set appropriate insamplesize to allow bitmapfactory to allocate less space//with proper insamplesize decode bitmapfactory.options O2 = new Bit 
   Mapfactory.options (); 
   O2.insamplesize = scale; 
  Return Bitmapfactory.decodestream (New FileInputStream (f), NULL, O2); 
 catch (FileNotFoundException e) {} return null; /** * Picturetoload class (including image address and ImageView object) * * @author LOONGGG */Private class Picturetoload {p 
  Ublic String URL; 
  Public ImageView ImageView; 
   Public Picturetoload (String u, imageview i) {url = u; 
  ImageView = i; }} public void Stopthread () {PictureloaDerthread.interrupt (); ///Store downloaded photo List class Picturesqueue {private stack<picturetoload> picturestoload = new Stack<picturetoload 
  > (); Deletes all instances of this imageview public void clean (ImageView image) {for (int j = 0; J < picturestoload.size ();) 
    {if (Picturestoload.get (j). ImageView = = image) Picturestoload.remove (j); 
   else ++j; 
     "}}//Picture loading thread class Picturesloader extends thread {public void run () {try {a while (true)} { Threads wait until there is a picture loaded in the queue if (picturesQueue.picturesToLoad.size () = = 0) synchronized (picturesqueue.picturestoload) 
      {picturesQueue.picturesToLoad.wait (); 
      } if (PicturesQueue.picturesToLoad.size ()!= 0) {picturetoload phototoload; 
      Synchronized (picturesqueue.picturestoload) {phototoload = PicturesQueue.picturesToLoad.pop (); 
      Bitmap bmp = Getbitmap (Phototoload.url); Write to the phone in memory Memorycache.put (Phototoload.url, BMP); 
      String tag = Imageviews.get (Phototoload.imageview); 
         if (tag!= null && tag.equals (Phototoload.url)) {bitmapdisplayer BD = new Bitmapdisplayer (BMP, 
       Phototoload.imageview); 
       Activity activity = (activity) Phototoload.imageview. GetContext (); 
      Activity.runonuithread (BD); 
    } if (thread.interrupted ()) break; The catch (Interruptedexception e) {//Allow thread to exit}}/////Bitmap Image Class Bitmapdisplayer im in UI thread 
  Plements Runnable {Bitmap Bitmap; 
  ImageView ImageView; 
   Public Bitmapdisplayer (Bitmap Bitmap, ImageView imageview) {this.bitmap = Bitmap; 
  This.imageview = ImageView; 
   public void Run () {if (bitmap!= null) imageview.setimagebitmap (bitmap); 
  else Imageview.setimageresource (stub_id); 
  } public void ClearCache () {memorycache.clear (); 
 Filecache.clear (); 

 } 
}

4, followed by several entity classes, one is cached to the SD card entity class, there is a cache to the phone in the memory of the entity class. The code is as follows:

(1), the entity class that caches to SD card:

Package net.loonggg.util; 
Import Java.io.File; 
Import Android.content.Context; 
public class Filecache { 
 private File cachedir; 
 Public Filecache { 
  //Find a picture directory to save the cache 
  if (Android.os.Environment.getExternalStorageState (). Equals ( 
    Android.os.Environment.MEDIA_MOUNTED)) 
   Cachedir = new File ( 
     Android.os.Environment.getExternalStorageDirectory (), 
     "Newnews"); 
  else 
   Cachedir = Context.getcachedir (); 
  if (!cachedir.exists ()) 
   cachedir.mkdirs (); 
 } 
 Public File getFile (string url) { 
  string filename = string.valueof (Url.hashcode ()); 
  File F = new file (cachedir, filename); 
  return f; 
 } 
 public void Clear () { 
  file[] files = cachedir.listfiles (); 
  for (File f:files) 
   f.delete (); 
 } 
 

(2), cached to the cell phone memory entity class:

Package net.loonggg.util; 
Import java.lang.ref.SoftReference; 
Import Java.util.HashMap; 
Import Android.graphics.Bitmap; 
public class MemoryCache { 
 private hashmap<string, softreference<bitmap>> cache=new hashmap<string , softreference<bitmap>> (); 
 Public Bitmap get (String ID) { 
  if (!cache.containskey (ID)) return 
   null; 
  Softreference<bitmap> ref=cache.get (ID); 
  return Ref.get (); 
 } 
 public void put (String ID, Bitmap Bitmap) { 
  cache.put (ID, new softreference<bitmap> (Bitmap)); 
 public void Clear () { 
  cache.clear (); 
 } 
} 

5, this is the input and output stream conversion classes, and methods:

Package net.loonggg.util; 
Import Java.io.InputStream; 
Import Java.io.OutputStream; 
public class Imageutil {public 
 static void CopyStream (InputStream is, OutputStream os) { 
  final int buffer_size = 1024; 
  try { 
   byte[] bytes = new Byte[buffer_size]; 
   for (;;) { 
    int count = is.read (bytes, 0, buffer_size); 
    if (count = = 1) break 
     ; 
    Os.write (bytes, 0, count); 
   } 
  catch (Exception ex) { 
  } 
 } 
} 

It's basically done here.

I hope this article will help you with the Android program.

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.