1# Obtaining the Recently Accessed List 2 3To quickly access the recently used [Sendable](arkts-sendable.md) objects, ArkTS introduces [SendableLruCache](../reference/apis-arkts/js-apis-arkts-utils.md#sendablelrucachek-v18) since API version 18. With this class, you can add, delete, and obtain Sendable objects from a SendableLruCache instance to quickly access the recently used Sendable objects. This topic describes how to use SendableLruCache to obtain the recently accessed list. It uses a bookshelf as an example. Every time a user opens a book, the book information is updated to the recently accessed list. When the user accesses the bookshelf next time, the list of books that the user has looked at is displayed. 4 5> **NOTE** 6> 7> SendableLruCache instances must be locked to prevent data inconsistency caused by concurrent operations from multiple threads. 8> 9> Only Sendable objects can be put into a SendableLruCache instance. 10 111. Create a SendableLruCache instance and set its maximum capacity based on service requirements. 12 13 In this example, the maximum capacity of the SendableLruCache instance is set to 4, the Sendable class is used for management, and the Sendable class instance is exported. 14 15 ```ts 16 // LruCache.ets 17 18 import { ArkTSUtils } from '@kit.ArkTS'; 19 20 // Use the 'use shared' marker to make the Sendable class instance shareable across different threads. 21 "use shared" 22 23 @Sendable 24 class SendableClass { 25 // Lock the SendableLruCache instances to prevent data inconsistency caused by concurrent operations from multiple threads. 26 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); 27 books_: ArkTSUtils.SendableLruCache<string, string> = new ArkTSUtils.SendableLruCache<string, string>(4); 28 29 constructor() { 30 this.books_.put("fourth", "Book4"); 31 this.books_.put("third", "Book3"); 32 this.books_.put("second", "Book2"); 33 this.books_.put("first", "Book1"); 34 } 35 36 // Wrap the put, get, and keys methods and perform the lock operation. 37 public async put(key: string, value: string) { 38 await this.lock_.lockAsync(() => { 39 this.books_.put(key, value); 40 }) 41 } 42 43 public async get(key: string): Promise<string | undefined> { 44 return this.lock_.lockAsync(() => { 45 return this.books_.get(key); 46 }); 47 } 48 49 public async keys(): Promise<string[]> { 50 return this.lock_.lockAsync(() => { 51 return this.books_.keys(); 52 }); 53 } 54 } 55 56 export let lruCache = new SendableClass(); 57 ``` 58 592. In the same directory as the **Index.ets** page, create four book pages. Each page shows its own book information. Register the path of each page in the **main_pages.json** file under **src/main/resources/base/profile/**. 60 61 ```ts 62 // Book1.ets 63 64 import { router } from '@kit.ArkUI'; 65 66 @Entry 67 @Component 68 struct Index1 { 69 @State message: string = 'Hello World!'; 70 71 build() { 72 RelativeContainer() { 73 Text("Content of book 1") 74 .id('first book') 75 .fontSize(20) 76 .padding(10) 77 .fontWeight(FontWeight.Bold) 78 .alignRules({ 79 center: { anchor: 'container', align: VerticalAlign.Center }, 80 middle: { anchor: 'container', align: HorizontalAlign.Center } 81 }) 82 Button('Back') 83 .fontSize(20) 84 .padding(10) 85 .fontWeight(FontWeight.Bold) 86 .onClick(() => { 87 router.pushUrl({ 88 url: 'pages/Index', 89 }); 90 }) 91 } 92 .height('100%') 93 .width('100%') 94 } 95 } 96 ``` 97 ```ts 98 // Book2.ets 99 100 import { router } from '@kit.ArkUI'; 101 102 @Entry 103 @Component 104 struct Index2 { 105 @State message: string = 'Hello World!'; 106 107 build() { 108 RelativeContainer() { 109 Text("Content of book 2") 110 .id('second book') 111 .fontSize(20) 112 .padding(10) 113 .fontWeight(FontWeight.Bold) 114 .alignRules({ 115 center: { anchor: 'container', align: VerticalAlign.Center }, 116 middle: { anchor: 'container', align: HorizontalAlign.Center } 117 }) 118 Button('Back') 119 .fontSize(20) 120 .padding(10) 121 .fontWeight(FontWeight.Bold) 122 .onClick(() => { 123 router.pushUrl({ 124 url: 'pages/Index', 125 }); 126 }) 127 } 128 .height('100%') 129 .width('100%') 130 } 131 } 132 ``` 133 ```ts 134 // Book3.ets 135 136 import { router } from '@kit.ArkUI'; 137 138 @Entry 139 @Component 140 struct Index3 { 141 @State message: string = 'Hello World!'; 142 143 build() { 144 RelativeContainer() { 145 Text("Content of book 3") 146 .id('third book') 147 .fontSize(20) 148 .padding(10) 149 .fontWeight(FontWeight.Bold) 150 .alignRules({ 151 center: { anchor: 'container', align: VerticalAlign.Center }, 152 middle: { anchor: 'container', align: HorizontalAlign.Center } 153 }) 154 Button('Back') 155 .fontSize(20) 156 .padding(10) 157 .fontWeight(FontWeight.Bold) 158 .onClick(() => { 159 router.pushUrl({ 160 url: 'pages/Index', 161 }); 162 }) 163 } 164 .height('100%') 165 .width('100%') 166 } 167 } 168 ``` 169 ```ts 170 // Book4.ets 171 172 import { router } from '@kit.ArkUI'; 173 174 @Entry 175 @Component 176 struct Index4 { 177 @State message: string = 'Hello World!'; 178 179 build() { 180 RelativeContainer() { 181 Text("Content of book 4") 182 .id('fourth book') 183 .fontSize(20) 184 .padding(10) 185 .fontWeight(FontWeight.Bold) 186 .alignRules({ 187 center: { anchor: 'container', align: VerticalAlign.Center }, 188 middle: { anchor: 'container', align: HorizontalAlign.Center } 189 }) 190 Button('Back') 191 .fontSize(20) 192 .padding(10) 193 .fontWeight(FontWeight.Bold) 194 .onClick(() => { 195 router.pushUrl({ 196 url: 'pages/Index', 197 }); 198 }) 199 } 200 .height('100%') 201 .width('100%') 202 } 203 } 204 ``` 205 ```json 206 // main_pages.json 207 208 { 209 "src": [ 210 "pages/Index", 211 "pages/Book1", 212 "pages/Book2", 213 "pages/Book3", 214 "pages/Book4" 215 ] 216 } 217 ``` 218 2193. Each time a user accesses the bookshelf page, the application automatically obtains and displays the list of recently accessed books. 220 221 ```ts 222 // Index.ets 223 224 import { taskpool } from '@kit.ArkTS'; 225 import { router } from '@kit.ArkUI'; 226 import { lruCache } from './LruCache' 227 228 @Concurrent 229 async function updateBooks(key: string, value: string) { 230 // Update the latest access list in the child thread. 231 await lruCache.put(key, value); 232 } 233 234 @Entry 235 @Component 236 struct Index { 237 @State message: string = 'Bookshelf' 238 @State books: string[] = []; 239 240 async aboutToAppear () { 241 // The application automatically obtains the list of recently accessed books. 242 this.books = await lruCache.keys(); 243 } 244 245 build() { 246 Column({ space: 1 }) { 247 Text(this.message) 248 .id('HelloWorld') 249 .fontSize(50) 250 .fontWeight(FontWeight.Bold) 251 .alignRules({ 252 center: { anchor: 'container', align: VerticalAlign.Center }, 253 middle: { anchor: 'container', align: HorizontalAlign.Center } 254 }) 255 Button(this.books[3]) 256 .fontSize(20) 257 .padding(10) 258 .fontWeight(FontWeight.Bold) 259 .onClick(async () => { 260 // Obtain the bound book information. 261 let value = await lruCache.get(this.books[3]); 262 // Update the recently accessed list. 263 taskpool.execute(updateBooks, this.books[3], value); 264 router.pushUrl({ 265 url: 'pages/' + value, 266 }); 267 }) 268 Button(this.books[2]) 269 .fontSize(20) 270 .padding(10) 271 .fontWeight(FontWeight.Bold) 272 .onClick(async () => { 273 // Obtain the bound book information. 274 let value = await lruCache.get(this.books[2]); 275 // Update the recently accessed list. 276 taskpool.execute(updateBooks, this.books[2], value); 277 router.pushUrl({ 278 url: 'pages/' + value, 279 }); 280 }) 281 Button(this.books[1]) 282 .fontSize(20) 283 .padding(10) 284 .fontWeight(FontWeight.Bold) 285 .onClick(async () => { 286 // Obtain the bound book information. 287 let value = await lruCache.get(this.books[1]); 288 // Update the recently accessed list. 289 taskpool.execute(updateBooks, this.books[1], value); 290 router.pushUrl({ 291 url: 'pages/' + value, 292 }); 293 }) 294 Button(this.books[0]) 295 .fontSize(20) 296 .padding(10) 297 .fontWeight(FontWeight.Bold) 298 .onClick(async () => { 299 // Obtain the bound book information. 300 let value = await lruCache.get(this.books[0]); 301 // Update the recently accessed list. 302 taskpool.execute(updateBooks, this.books[0], value); 303 router.pushUrl({ 304 url: 'pages/' + value, 305 }); 306 }) 307 } 308 .height('100%') 309 .width('100%') 310 } 311 } 312 ```