[Easy moment] practical project development (2) list data deduplication data append and cache, easy moment Project Development

Source: Internet
Author: User
Tags addall

[Easy moment] practical project development (2) list data deduplication data append and cache, easy moment Project Development

Open-source control PullToRefresh is introduced to refresh the list from the drop-down menu.

 

Each pull-down refresh will send a request and return json information from the interface.

How to remove duplicates from the list if duplicate data exists in the returned data of the first and second requests?

 

In the previous article, we overwrote the hashcode and equals methods of the object Data.

/*** Because the Update Time and unixtime are not unique * use the unique hashId to obtain the hash code */@ Override public int hashCode () {final int prime = 31; int result = 1; result = prime * result + (hashId = null )? 0: hashId. hashCode (); return result ;} /*** because the Update Time and unixtime are not unique * Here we use the unique hashId to compare */@ Override public boolean equals (Object obj) {if (this = obj) return true; if (obj = null) return false; if (getClass ()! = Obj. getClass () return false; Data other = (Data) obj; if (hashId = null) {if (other. hashId! = Null) return false;} else if (! HashId. equals (other. hashId) return false; return true ;}

Because only hashId is a unique identifier in data, we use it for comparison.

 

Removing duplicates using the feature that cannot be added to the set element as the judgment Condition

/*** Override the hashCode and equals methods in Data * use the set feature that cannot be used to add new elements as the judgment condition * put non-repeated data elements into a temporary newlist in sequence * after the loop is completed, clear the original list, addAll (newlist) * @ param list * @ return */public static List <Data> removeDuplicateDataInOrder (List <Data> list) {HashSet <Data> hashSet = new HashSet <Data> (); List <Data> newlist = new ArrayList <Data> (); for (Iterator iterator = list. iterator (); iterator. hasNext ();) {Data element = (Data) iterator. next (); if (hashSet. add (element) {newlist. add (element) ;}} list. clear (); list. addAll (newlist); return list ;}

 

To ensure the order of data arrangement, we should perform the following operations before deduplication:

1. If it is a pull-down refresh, add the data to the list header list. addAll (0, list <T>)
2. load more data to the end of list. addAll (list <T>)

 

The aggregate data interface can also return the joke list before or after the timestamp.

Request example:Http://japi.juhe.cn/joke/content/list.from? Key = KEY & page = 2 & pagesize = 10 & sort = asc & time = 1418745237

In the parameter, sort param sort desc: published before the specified time. asc: published after the specified time. time indicates the timestamp.

 

Therefore, we use this request method to load more data in the above pull, and return the joke list before this time point with the timestamp of the last data in the current list as the node.

Therefore, there is no need to repeat the list,

If (flag = PULL_DOWN_REFRESH_FLAG) {// Add the newly refreshed data to the dataset header mCurrentListItems. addAll (0, result. getResult (); // remove the duplicate data in the list. mCurrentListItems = UtilsHelper. removeDuplicateDataInOrder (mCurrentListItems);} else if (flag = PULL_UP_REFRESH_FLAG) {// Add the newly loaded data to the end of the dataset // because the last data is queried forward with the timestamp, therefore, there are no duplicates. You do not need to deduplicate mCurrentListItems in the list. addAll (result. getResult (); pullUpPageNumber ++ ;}

 

How can we get the number of data records updated after this request? It is easy to save the last list and compare it with the size of the latest list.

Use handler to process and update the UI in the main thread

if(mLastListItems != null){    int count = mCurrentListItems.size() - mLastListItems.size();        android.os.Message msg = new android.os.Message();    msg.what = UPDATE_DATA_COUNT_MESSAGE;    msg.arg1 = count;    mHandler.sendMessage(msg);}

 

Then, the adapter dataset is notified to change and the onRefreshComplete () method of listview (listview is the instance of PullToRefreshListView) is called.

// The notification program dataset has changed. If no notification is sent, the mListItems collection mAdapter. notifyDataSetChanged (); mListView. onRefreshComplete () will not be refreshed ();

 

If we are in a non-network environment, it is necessary to create a cache for offline viewing. It is best to cache the list data displayed when we exited the application last time.

Sqlite is not used. Files are temporarily used and cached to a directory of sdcard (/storage/emulated/0/qingsongyike/cache)

Public static void saveJsonTextInLocalFile (String jsonData) {boolean sdCardExist = Environment. getExternalStorageState (). equals (android. OS. environment. MEDIA_MOUNTED); // determines whether the SD card exists if (sdCardExist) {Log. d ("UtilsHelper", "sdcard exist. "); File root = Environment. getExternalStorageDirectory (); String path = root. getPath () + File. separator + "qingsongyike" + File. separator + "cache"; Log. d ("UtilsHelper", "dir p Ath = "+ path); File file = new File (path); if (! File. exists () {file. mkdirs (); Log. d ("UtilsHelper", "cache dir had create finished. ");} File cacheFile = new File (path + File. separator + "cache.txt"); if (! CacheFile. exists () {try {cacheFile. createNewFile (); Log. d ("UtilsHelper", "file path =" + path); Log. d ("UtilsHelper", "cache file is created. ");} catch (IOException e) {e. printStackTrace () ;}try {synchronized (obj) {FileOutputStream fos = new FileOutputStream (cacheFile, false); OutputStreamWriter writer = new OutputStreamWriter (fos); writer. write (jsonData); writer. flush (); writer. close (); fos. close ();} Log. d ("UtilsHelper", "cache data write finished. "); // fos. write (JsonData. getBytes (); // fos. flush ();} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace () ;}} else {Log. d ("UtilsHelper", "sdcard is not exist. create cache file failed ");}}

 

Then we need to reassemble the list data into an object and use the gson api function to convert the bean into a json string.

Open a subthread to perform IO operations

Class CacheThread implements Runnable {@ Override public void run () {// perform the cache operation to refresh the latest data to form an object and convert it to a Json character. // if there are not 50 data refresh items, the cache will be cached. // if there are more than 50 data records, only the first 50 data records will be cached/ /avoid slow reading speed of cached files. String jsonData = null; list <Data> list = new ArrayList <Data> (); list. addAll (mCurrentListItems); if (list. size ()> 0 & list. size () <50) {jsonData = UtilsHelper. beanConvertToJson (new Message (0, "Success", list);} else if (list. size ()> = 50 ){// Remove Log. d ("CacheThread", "list size is more than 50 !! "); For (int I = list. size ()-1; I> = 50; I --) {list. remove (I);} Log. d ("CacheThread", "list remove finish. size now is 50 !! "); JsonData = UtilsHelper. beanConvertToJson (new Message (0," Success ", list);} else {Log. d (" CacheThread "," list size is 0 !! ") ;}// Save the Json character locally so that you can browse if (jsonData! = Null) {UtilsHelper. saveJsonTextInLocalFile (jsonData);} else {Log. d ("CacheThread", "jsonData is null !! ");}}}

Only up to 50 pieces of joke information will be intercepted to avoid the slow reading and writing caused by large data volumes.

 

The function for converting bean into a json string is as follows:

// Bean conversion json public static String beanConvertToJson (Object obj) {Gson gson = new Gson (); String json = gson. toJson (obj); Log. d ("UtilsHelper", "json =" + json); return json ;}

 

Do not forget to add the sdcard operation and file read/write permissions in AndroidiManfest. xml.

<! -- Create and delete file permissions in SDCard --> <uses-permission android: name = "android. permission. MOUNT_UNMOUNT_FILESYSTEMS"/> <! -- Write data permission to SDCard --> <uses-permission android: name = "android. permission. WRITE_EXTERNAL_STORAGE"/> <! -- Read data from SDCard --> <uses-permission android: name = "android. permission. READ_EXTERNAL_STORAGE"/>

 

As long as there is updated data, we will execute a local cache operation.

 

 

The file content has been written.

 

Not complete...

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.