• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 mark a module shareable.
21   "use shared"
22
23   // The SendableClass instance can be shared across different threads.
24   @Sendable
25   class SendableClass {
26     // Lock the SendableLruCache instances to prevent data inconsistency caused by concurrent operations from multiple threads.
27     lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();
28     books_: ArkTSUtils.SendableLruCache<string, string> = new ArkTSUtils.SendableLruCache<string, string>(4);
29
30     constructor() {
31       this.books_.put("fourth", "Book4");
32       this.books_.put("third", "Book3");
33       this.books_.put("second", "Book2");
34       this.books_.put("first", "Book1");
35     }
36
37     // Wrap the put, get, and keys methods and perform the lock operation.
38     public async put(key: string, value: string) {
39       await this.lock_.lockAsync(() => {
40         this.books_.put(key, value);
41       })
42     }
43
44     public async get(key: string): Promise<string | undefined> {
45       return this.lock_.lockAsync(() => {
46         return this.books_.get(key);
47       });
48     }
49
50     public async keys(): Promise<string[]> {
51       return this.lock_.lockAsync(() => {
52         return this.books_.keys();
53       });
54     }
55   }
56
57   export let lruCache = new SendableClass();
58   ```
59
602. 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/**.
61
62   ```ts
63   // Book1.ets
64
65   @Entry
66   @Component
67   struct Index1 {
68     @State message: string = 'Hello World!';
69
70     build() {
71       RelativeContainer() {
72         Text("Content of book 1")
73           .id('first book')
74           .fontSize(20)
75           .padding(10)
76           .fontWeight(FontWeight.Bold)
77           .alignRules({
78             center: { anchor: 'container', align: VerticalAlign.Center },
79             middle: { anchor: 'container', align: HorizontalAlign.Center }
80           })
81         Button('Back')
82           .fontSize(20)
83           .padding(10)
84           .fontWeight(FontWeight.Bold)
85           .onClick(() => {
86             this.getUIContext().getRouter().pushUrl({ url: 'pages/Index' });
87           })
88       }
89       .height('100%')
90       .width('100%')
91     }
92   }
93   ```
94   ```ts
95   // Book2.ets
96
97   @Entry
98   @Component
99   struct Index2 {
100     @State message: string = 'Hello World!';
101
102     build() {
103       RelativeContainer() {
104         Text("Content of book 2")
105           .id('second book')
106           .fontSize(20)
107           .padding(10)
108           .fontWeight(FontWeight.Bold)
109           .alignRules({
110             center: { anchor: 'container', align: VerticalAlign.Center },
111             middle: { anchor: 'container', align: HorizontalAlign.Center }
112           })
113         Button('Back')
114           .fontSize(20)
115           .padding(10)
116           .fontWeight(FontWeight.Bold)
117           .onClick(() => {
118             this.getUIContext().getRouter().pushUrl({ url: 'pages/Index' });
119           })
120       }
121       .height('100%')
122       .width('100%')
123     }
124   }
125   ```
126   ```ts
127   // Book3.ets
128
129   @Entry
130   @Component
131   struct Index3 {
132     @State message: string = 'Hello World!';
133
134     build() {
135       RelativeContainer() {
136         Text("Content of book 3")
137           .id('third book')
138           .fontSize(20)
139           .padding(10)
140           .fontWeight(FontWeight.Bold)
141           .alignRules({
142             center: { anchor: 'container', align: VerticalAlign.Center },
143             middle: { anchor: 'container', align: HorizontalAlign.Center }
144           })
145         Button('Back')
146           .fontSize(20)
147           .padding(10)
148           .fontWeight(FontWeight.Bold)
149           .onClick(() => {
150             this.getUIContext().getRouter().pushUrl({ url: 'pages/Index' });
151           })
152       }
153       .height('100%')
154       .width('100%')
155     }
156   }
157   ```
158   ```ts
159   // Book4.ets
160
161   @Entry
162   @Component
163   struct Index4 {
164     @State message: string = 'Hello World!';
165
166     build() {
167       RelativeContainer() {
168         Text("Content of book 4")
169           .id('fourth book')
170           .fontSize(20)
171           .padding(10)
172           .fontWeight(FontWeight.Bold)
173           .alignRules({
174             center: { anchor: 'container', align: VerticalAlign.Center },
175             middle: { anchor: 'container', align: HorizontalAlign.Center }
176           })
177         Button('Back')
178           .fontSize(20)
179           .padding(10)
180           .fontWeight(FontWeight.Bold)
181           .onClick(() => {
182             this.getUIContext().getRouter().pushUrl({ url: 'pages/Index' });
183           })
184       }
185       .height('100%')
186       .width('100%')
187     }
188   }
189   ```
190   ```json
191   // main_pages.json
192
193   {
194     "src": [
195       "pages/Index",
196       "pages/Book1",
197       "pages/Book2",
198       "pages/Book3",
199       "pages/Book4"
200     ]
201   }
202   ```
203
2043. Each time a user accesses the bookshelf page, the application displays the list of recently accessed books.
205
206   ```ts
207   // Index.ets
208
209   import { taskpool } from '@kit.ArkTS';
210   import { lruCache } from './LruCache'
211
212   @Concurrent
213   async function updateBooks(key: string, value: string) {
214     // Update the latest access list in the child thread.
215     await lruCache.put(key, value);
216   }
217
218   @Entry
219   @Component
220   struct Index {
221     @State message: string = 'Bookshelf'
222     @State books: string[] = [];
223
224     async aboutToAppear () {
225       // The application automatically obtains the list of recently accessed books.
226       this.books = await lruCache.keys();
227     }
228
229     build() {
230       Column({ space: 1 }) {
231         Text(this.message)
232           .id('HelloWorld')
233           .fontSize(50)
234           .fontWeight(FontWeight.Bold)
235           .alignRules({
236             center: { anchor: 'container', align: VerticalAlign.Center },
237             middle: { anchor: 'container', align: HorizontalAlign.Center }
238           })
239         Button(this.books[3])
240           .fontSize(20)
241           .padding(10)
242           .fontWeight(FontWeight.Bold)
243           .onClick(async () => {
244             // Obtain the bound book information.
245             let value = await lruCache.get(this.books[3]);
246             // Update the recently accessed list.
247             taskpool.execute(updateBooks, this.books[3], value);
248             this.getUIContext().getRouter().pushUrl({ url: 'pages/' + value });
249           })
250         Button(this.books[2])
251           .fontSize(20)
252           .padding(10)
253           .fontWeight(FontWeight.Bold)
254           .onClick(async () => {
255             // Obtain the bound book information.
256             let value = await lruCache.get(this.books[2]);
257             // Update the recently accessed list.
258             taskpool.execute(updateBooks, this.books[2], value);
259             this.getUIContext().getRouter().pushUrl({ url: 'pages/' + value });
260           })
261         Button(this.books[1])
262           .fontSize(20)
263           .padding(10)
264           .fontWeight(FontWeight.Bold)
265           .onClick(async () => {
266             // Obtain the bound book information.
267             let value = await lruCache.get(this.books[1]);
268             // Update the recently accessed list.
269             taskpool.execute(updateBooks, this.books[1], value);
270             this.getUIContext().getRouter().pushUrl({ url: 'pages/' + value });
271           })
272         Button(this.books[0])
273           .fontSize(20)
274           .padding(10)
275           .fontWeight(FontWeight.Bold)
276           .onClick(async () => {
277             // Obtain the bound book information.
278             let value = await lruCache.get(this.books[0]);
279             // Update the recently accessed list.
280             taskpool.execute(updateBooks, this.books[0], value);
281             this.getUIContext().getRouter().pushUrl({ url: 'pages/' + value });
282           })
283       }
284       .height('100%')
285       .width('100%')
286     }
287   }
288   ```
289