Android optimized query loads a large number of local album Pictures _android

Source: Internet
Author: User

I. Overview

Explain the optimization query photo album, before we look at the requirements of the PM, PM's demand is very simple, is to do a similar micro-letter local Photo album query control, mainly contains two two parts:

    • Enter the image selection page to display all the photos on the phone, including the system photo album and all the pictures in the other directory, and in chronological order.
    • Switch photo album feature, switch album page List all the pictures in the phone list, and show the number of all the pictures in each directory and the cover picture

These two requirements seemingly simple, but in fact hidden a series of performance optimization problems. Before we did the optimization, we investigated some of the performance features of some of the more famous apps in loading large numbers of images (GIF recordings are not clear enough, but the problem has been demonstrated enough):

Here are a few common software tests

Wechat:
Micro-letter Image query speed is very fast, basically into the picture Selection page, album data has been found out, including the various picture directories under the number of pictures and cover pictures of the URL, this experience is relatively good.

Sina Micro Blog:
Compared to the micro-letter, Sina Weibo experience is relatively poor, into the picture selection page, first black screen then is screen, even a progress bar, so that users think app died, and so on a period of time before showing out, this experience is poor

Qq:
QQ one up is loaded with the last 100 photos, this is very fast, but after entering the camera album (there are more than 5,000), there is a progress bar waiting, I experienced, the waiting time is still relatively long, this experience than Sina Weibo slightly better, than the micro-messenger

Free Fish:
Leisure fish is to do the worst one, a card to die four or five seconds, then the black screen two or three seconds, the last show out

Second, comprehensive comparison

After a comprehensive comparison, the micro-letter to do is still relatively good, basically into the album page will be able to show all the photos, albums directory is also very quickly displayed!!!

After our investigation, we found that the micro-letter is a cyclic paging loading strategy, we optimize the idea is to adopt this strategy, first look at the optimization of the effect chart:

Enter the image selection page, the picture can be very quickly displayed, into the replacement album page, the picture directory can also be very quick display, there is no such as micro-letter to do the image directory cache: First, because the query speed is very fast, basically less than 2 seconds to load out, and second, can be real-time refresh the latest album of data

Frequent switch to each album directory, pictures can be very fast query out, experience or a good!!!

Third, optimize the realization

Optimize Query Album Directory

Because to enumerate all albums directory list, there is no other good way, direct request Contentresolver Query method to inquire, here in order to speed up the query, remove some of the while loop time of judgment, will some detection picture whether the logic of judgment to move outside, Use the time to judge

Query the URI of a picture

MediaStore.Images.Media.EXTERNAL_CONTENT_URI

Because we only query the picture URL and the directory where the picture is located

string[] projection = {MediaStore.Images.ImageColumns.DATA, MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME};

PM Request album According to the time of the picture in flashbacks, the creation of pictures, changes will affect the sort of the directory, sorted by time flashbacks

String SortOrder = MediaStore.Images.Media.DATE_TAKEN + "DESC";

Based on these query criteria, we get a cursor after query, this cursor contains information about all the pictures we need, and then we loop through the cursor while the while loop must not have time-consuming operations

An auxiliary set to prevent the same directory from being scanned multiple times hashset<string> dirpaths = new hashset<string> (); while (Cursor.movetonext ()) {//Get the path of the picture String path = cursor.getstring (Cursor.getcolumnindex MediaStore.Images.ImageC Olumns.
  DATA));

  String bucketname = cursor.getstring (Cursor.getcolumnindex (MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME));
  if (Textutils.isempty (Allfolderitem.coverimagepath)) {allfolderitem.coverimagepath = path;
  File Parentfile = new file (path). Getparentfile ();

  if (Parentfile = = null) continue;

  String Dirpath = Parentfile.getabsolutepath ();
  Picfolderitem FolderItem = null;
  Use a hashset to prevent multiple scans of the same folder (without this judgment, the picture is more or less scary ~ ~) if (Dirpaths.contains (Dirpath)) {continue;

    else {dirpaths.add (dirpath);
    Boolean isnew = true;
        Determine if Dirpath is different, but bucketname the same for (Picfolderitem item:piclist) {if (Item.name.equals (Bucketname)) {
        FolderItem = Item;
        Item.addparentpath (Dirpath);
        IsNew = false; BreAk
      } if (isnew) {FolderItem = new Picfolderitem ();
      Folderitem.coverimagepath = path;
      Folderitem.name = Bucketname;
    Folderitem.addparentpath (Dirpath); } string[] Array = parentfile.list (new FilenameFilter () {@Override public boolean accept (File dir, String FileName) {if (Filename.endswith (". jpg") | | filename.endswith (". png") | | filename.endswith (". JP
      Eg ") return true;
    return false;

  }
  }); int arraycount = Array = = NULL?
  0:array.length;
  Folderitem.count + = Arraycount;
  if (!piclist.contains (folderitem) && arraycount > 0) {piclist.add (FolderItem);

 }
}

This makes it very quick to find out all the pictures in the phone, the number of pictures in the catalogue, and the cover page URL. Here the main optimization of three points:

Removing time-consuming judgments in while loops

There is code in the previous code that determines whether a file picture exists:

 public static Boolean isfileexist (String path) {
  file File = new file (path);
  if (file = = NULL | |!file.exists ()) {return
    false;
  }
  return true;
  }

This code is very scary to put in the while loop, and I tested that the total time would be increased by three or four seconds for more than 5,000 images. This judgment can be put outside, the specific operation of a picture of the time to do a specific business judgment!

Prevent a picture folder from being scanned multiple times

A variable is added here to store the scanned picture directory, and the scanned one is not processed:

An auxiliary set to prevent the Unified directory query multiple
hashset<string> dirpaths = new hashset<string> ();

After the optimization of the effect is still very obvious, the same directory will not scan multiple times!

Get the number of pictures in the picture directory

string[] Array = parentfile.list (new FilenameFilter () {
            @Override public
            boolean Accept (File dir, String FileName) {
              if (Filename.endswith (". jpg")
                  | | filename.endswith (". png")
                  | | filename.endswith (". jpeg") return
                true;
              return false;
            }
          });

The interior of this file.list () method is a native method, and the query efficiency is very fast!!!

Of course, get a picture of a directory of how many can also be cursor query way to get!!!

Query for all photos in an album directory

In the introduction of the query directory before the photos, we first introduce the two strategies we query the picture, one is for the directory under the picture is more, not at all, the kind of thousands of thousand Zhang; the other is that kind of catalogue with fewer pictures than hundreds of pictures

Load Policy Once

When the number of pictures under the directory is less than 1000, using file.list This native method to load all the pictures at once, this native query efficiency is very fast, thousands of pictures are second-level query out

Cyclic Paging load Policy

When the number of pictures is greater than or equal to 1000, a cyclic paging loading strategy is used. This strategy specifically for the number of pictures in particular, the first page of the way through the page to load out, so that users can first see the latest picture, and then the background of the asynchronous Loop query next page of pictures, until all the pictures are completed query, This is also a micro-letter query album strategy.

Implementation of one load policy

Here we look at the next loading policy implementation code, first through the file's list method to filter the suffix to the picture format files, return a picture path array

File Dirfile = new file (dir);
string[] List = dirfile.list (new FilenameFilter () {
  @Override public
  boolean Accept (File dir, String filename) { C5/>if (Filename.endswith (". jpg") | | | Filename.endswith (". png")
        | | | filename.endswith (". jpeg")) return
      true;
    return false;
  }
});

Because we want an array of chronological flashbacks, we want to sort the array of queries above, using the file LastModified method

Collections.sort (Strings, new comparator<string> () {
        @Override public
        int Compare (string lhs, String RHS {
          Long time1 = new File (LHS). LastModified ();
          Long time2 = new File (RHS). LastModified ();
          Return Time2.compareto (TIME1);
        }
        );

Implementation of cyclic paging load policy

This strategy draws on the micro-letter, through paging the way to a page to load the picture, until all the pictures are loaded complete.

The core here is the query conditions, you want to query a directory to add to the query parameters

String selection = MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME + "= '" + Directory name + "'";

This selection must not be written wrong, or the query can not come out

Because to pagination, SortOrder is not simply in the time of flashbacks to the line

String SortOrder = MediaStore.Images.Media.DATE_TAKEN + "DESC Limit" + page_size + "offset" + pageIndex * page_size;

Finally, loop through the cursor to get the picture path we want.

Page_size is a constant, indicating how many we want to query at once, we set here is 200, one query 200 data, pageindex is the first few pages of query, starting from 0

At the beginning of the query on the first page of data, when the query's data list size is greater than the size of the pagesize we want to query, we think that there is a next page, pageindex plus 1 loops query the next page until the query's list size is less than pagesize.

After a few steps of optimization, loading a local photo album is basically no problem. We passed the real machine test, the picture 5549, can be very fast query out, comparable to the micro-letter and Image Library.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.