การค้นหาแอป

AppSearch เป็นโซลูชันการค้นหาประสิทธิภาพสูงในอุปกรณ์สำหรับจัดการในพื้นที่ ที่จัดเก็บไว้และเป็นข้อมูลที่มีโครงสร้าง มี API สำหรับจัดทำดัชนีข้อมูลและดึงข้อมูล โดยใช้การค้นหาข้อความแบบเต็ม แอปพลิเคชันสามารถใช้ AppSearch เพื่อเสนอโฆษณาในแอปที่กำหนดเอง ความสามารถในการค้นหา ทำให้ผู้ใช้ค้นหาเนื้อหาได้แม้ในขณะออฟไลน์

แผนภาพแสดงการจัดทำดัชนีและการค้นหาภายใน AppSearch

AppSearch มีฟีเจอร์ดังต่อไปนี้

  • การใช้พื้นที่เก็บข้อมูลที่รวดเร็ว เน้นอุปกรณ์เคลื่อนที่เป็นหลัก และมีการใช้งาน I/O ต่ำ
  • การจัดทำดัชนีและการค้นหาชุดข้อมูลขนาดใหญ่ที่มีประสิทธิภาพสูง
  • การรองรับหลายภาษา เช่น อังกฤษและสเปน
  • การจัดอันดับความเกี่ยวข้องและการให้คะแนนการใช้งาน

เนื่องจากการใช้งาน I/O ต่ำกว่า AppSearch จึงใช้เวลาในการตอบสนองน้อยลงในการจัดทำดัชนีและการค้นหา ชุดข้อมูลขนาดใหญ่เมื่อเทียบกับ SQLite AppSearch ช่วยให้การค้นหาแบบข้ามประเภทง่ายขึ้น โดยการรองรับการค้นหาเดี่ยวในขณะที่ SQLite ผสานผลลัพธ์จากหลายตาราง

เรามาดูตัวอย่างเพลงสำหรับดูฟีเจอร์ของ AppSearch กัน ซึ่งเป็นแอปพลิเคชันที่จัดการเพลงโปรดของผู้ใช้ และช่วยให้ผู้ใช้ค้นหา ให้กับแอปเหล่านั้น ผู้ใช้เพลิดเพลินกับเพลงจากทั่วโลกโดยใช้ชื่อเพลงต่างๆ ซึ่ง AppSearch รองรับการจัดทำดัชนีและการค้นหาโดยตรงอยู่แล้ว เมื่อ ผู้ใช้ค้นหาเพลงจากชื่อเพลงหรือชื่อศิลปิน แอปพลิเคชันผ่านเพียง ส่งคำขอให้ AppSearch เรียกดูเพลงที่ตรงกันได้อย่างรวดเร็วและมีประสิทธิภาพ แอปพลิเคชันจะแสดงผลลัพธ์ ซึ่งทำให้ผู้ใช้เริ่มเล่นได้อย่างรวดเร็ว เพลงโปรดของพวกเขา

ตั้งค่า

หากต้องการใช้ AppSearch ในแอปพลิเคชัน ให้เพิ่มทรัพยากร Dependency ต่อไปนี้ลงใน ไฟล์ build.gradle ของแอปพลิเคชัน:

Groovy

dependencies {
    def appsearch_version = "1.1.0-alpha06"

    implementation "androidx.appsearch:appsearch:$appsearch_version"
    // Use kapt instead of annotationProcessor if writing Kotlin classes
    annotationProcessor "androidx.appsearch:appsearch-compiler:$appsearch_version"

    implementation "androidx.appsearch:appsearch-local-storage:$appsearch_version"
    // PlatformStorage is compatible with Android 12+ devices, and offers additional features
    // to LocalStorage.
    implementation "androidx.appsearch:appsearch-platform-storage:$appsearch_version"
}

Kotlin

dependencies {
    val appsearch_version = "1.1.0-alpha06"

    implementation("androidx.appsearch:appsearch:$appsearch_version")
    // Use annotationProcessor instead of kapt if writing Java classes
    kapt("androidx.appsearch:appsearch-compiler:$appsearch_version")

    implementation("androidx.appsearch:appsearch-local-storage:$appsearch_version")
    // PlatformStorage is compatible with Android 12+ devices, and offers additional features
    // to LocalStorage.
    implementation("androidx.appsearch:appsearch-platform-storage:$appsearch_version")
}

แนวคิดของ AppSearch

แผนภาพต่อไปนี้แสดงแนวคิดของ AppSearch และการโต้ตอบของแนวคิด

แผนภาพ
โครงร่างของแอปพลิเคชันไคลเอ็นต์และการโต้ตอบกับ
แนวคิดของ AppSearch: ฐานข้อมูล AppSearch, สคีมา, ประเภทสคีมา, เอกสาร
เซสชัน และการค้นหา รูปที่ 1 แผนภาพแนวคิดของ AppSearch: ฐานข้อมูล AppSearch, สคีมา, ประเภทสคีมา เอกสาร เซสชัน และการค้นหา

ฐานข้อมูลและเซสชัน

ฐานข้อมูล AppSearch คือคอลเล็กชันเอกสารที่สอดคล้องกับฐานข้อมูล สคีมา แอปพลิเคชันไคลเอ็นต์สร้างฐานข้อมูลด้วยการมอบแอปพลิเคชัน บริบทและชื่อฐานข้อมูล เฉพาะแอปพลิเคชันเท่านั้นที่สามารถเปิดฐานข้อมูลได้ ที่สร้างมันขึ้นมา เมื่อมีการเปิดฐานข้อมูล เซสชันจะถูกส่งคืนเพื่อโต้ตอบ กับฐานข้อมูล เซสชันคือจุดแรกเข้าสำหรับการเรียกใช้ AppSearch API และจะยังคงเปิดอยู่จนกว่าแอปพลิเคชันไคลเอ็นต์จะปิด

สคีมาและประเภทสคีมา

สคีมาแสดงโครงสร้างองค์กรของข้อมูลภายใน AppSearch ฐานข้อมูล

สคีมาประกอบด้วยประเภทสคีมาที่แสดงประเภทข้อมูลที่ไม่ซ้ำกัน ประเภทสคีมาประกอบด้วยพร็อพเพอร์ตี้ที่มีชื่อ ประเภทข้อมูล และ Cardinality เมื่อเพิ่มประเภทสคีมาในสคีมาฐานข้อมูลแล้ว เอกสารของ สามารถสร้างและเพิ่มสคีมาประเภทนั้นลงในฐานข้อมูลได้

เอกสาร

ใน AppSearch หน่วยข้อมูลจะแสดงเป็นเอกสาร เอกสารแต่ละรายการใน ฐานข้อมูล AppSearch จะได้รับการระบุโดยไม่ซ้ำกันด้วยเนมสเปซและรหัส เนมสเปซ ใช้เพื่อแยกข้อมูลจากแหล่งที่มาต่างๆ เมื่อต้องใช้แหล่งข้อมูลเพียงแหล่งเดียว ที่มีการค้นหา เช่น บัญชีผู้ใช้

เอกสารจะมีการประทับเวลาการสร้าง, Time to Live (TTL) และคะแนนที่ สามารถใช้ในการจัดอันดับระหว่างการดึงข้อมูลได้ ระบบกำหนดสคีมาให้กับเอกสารแล้ว ที่อธิบายพร็อพเพอร์ตี้ข้อมูลเพิ่มเติมที่เอกสารต้องมี

คลาสเอกสารคือนามธรรมของเอกสาร มีช่องที่มีคำอธิบายประกอบ ที่แสดงถึงเนื้อหาของเอกสาร โดยค่าเริ่มต้น ชื่อเอกสาร class จะตั้งชื่อของประเภทสคีมา

เอกสารจะได้รับการจัดทำดัชนีและค้นหาได้โดยการใส่คำค้นหา เอกสารคือ ตรงกับข้อความค้นหาและรวมอยู่ในผลการค้นหาด้วยหากมีคำที่อยู่ในข้อความค้นหา หรือตรงกับข้อกำหนดการค้นหาอื่น ผลลัพธ์มีการเรียงลำดับตาม คะแนนและกลยุทธ์การจัดอันดับ ผลการค้นหาจะแสดงด้วยหน้าที่คุณสามารถ ตามลำดับ

AppSearch มีการปรับแต่ง สำหรับการค้นหา เช่น ตัวกรอง การกำหนดค่าขนาดหน้า และข้อมูลโค้ด

พื้นที่เก็บข้อมูลของแพลตฟอร์มเทียบกับพื้นที่เก็บข้อมูลในเครื่อง

AppSearch มีโซลูชันพื้นที่เก็บข้อมูล 2 แบบ ได้แก่ LocalStorage และ PlatformStorage เมื่อใช้ LocalStorage แอปพลิเคชันของคุณจะจัดการดัชนีเฉพาะแอปที่ใช้งานอยู่ ไดเรกทอรีข้อมูลแอปพลิเคชันของคุณ เมื่อใช้ PlatformStorage แอปพลิเคชัน ทำให้เกิดดัชนีกลางทั้งระบบ การเข้าถึงข้อมูลภายในดัชนีกลาง จำกัดเฉพาะข้อมูลที่แอปพลิเคชันของคุณได้ให้ไว้และข้อมูล ที่แอปพลิเคชันอื่นแชร์กับคุณอย่างชัดเจน ทั้ง LocalStorage และ PlatformStorage ใช้ API เดียวกันและสลับกันได้ตาม เวอร์ชัน:

Kotlin

if (BuildCompat.isAtLeastS()) {
    appSearchSessionFuture.setFuture(
        PlatformStorage.createSearchSession(
            PlatformStorage.SearchContext.Builder(mContext, DATABASE_NAME)
               .build()
        )
    )
} else {
    appSearchSessionFuture.setFuture(
        LocalStorage.createSearchSession(
            LocalStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                .build()
        )
    )
}

Java

if (BuildCompat.isAtLeastS()) {
    mAppSearchSessionFuture.setFuture(PlatformStorage.createSearchSession(
            new PlatformStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                    .build()));
} else {
    mAppSearchSessionFuture.setFuture(LocalStorage.createSearchSession(
            new LocalStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                    .build()));
}

เมื่อใช้ PlatformStorage แอปพลิเคชันของคุณจะแชร์ข้อมูลกับผู้อื่นได้อย่างปลอดภัย แอปพลิเคชันเพื่อให้ค้นหาข้อมูลในแอปได้ด้วย อ่านอย่างเดียว จะมีการแชร์ข้อมูลแอปพลิเคชันผ่านแฮนด์เชคใบรับรองเพื่อให้แน่ใจว่า แอปพลิเคชันอื่นมีสิทธิ์ในการอ่านข้อมูล อ่านเพิ่มเติมเกี่ยวกับ API นี้ ในเอกสารประกอบสำหรับ setSchemaType visibilityForPackage()

นอกจากนี้ ข้อมูลที่มีการจัดทำดัชนีจะแสดงบนแพลตฟอร์ม UI ของระบบได้ด้วย แอปพลิเคชันสามารถเลือกไม่ใช้ข้อมูลบางส่วนหรือทั้งหมดที่แสดงในระบบได้ แพลตฟอร์ม UI อ่านเพิ่มเติมเกี่ยวกับ API นี้ในเอกสารประกอบสำหรับ setSchemaTypeDisplayedBySystem()

ฟีเจอร์ LocalStorage (compatible with Android 4.0+) PlatformStorage (compatible with Android 12+)
Efficient full-text search
Multi-language support
Reduced binary size
Application-to-application data sharing
Capability to display data on System UI surfaces
Unlimited document size and count can be indexed
Faster operations without additional binder latency

แต่ยังมีข้อดีอื่นๆ ที่ต้องพิจารณาเมื่อเลือกระหว่าง LocalStorage และ PlatformStorage เนื่องจาก PlatformStorage รวม API ของ Jetpack ไว้มากกว่า บริการระบบของ AppSearch ผลกระทบของขนาด APK นั้นน้อยที่สุด เมื่อเทียบกับการใช้ LocalStorage แต่หมายความว่าการดำเนินการของ AppSearch ยังต้องดำเนินการเพิ่ม เวลาในการตอบสนองของ Binder เมื่อเรียกใช้บริการของระบบ AppSearch PlatformStorage AppSearch จำกัดจำนวนเอกสารและขนาดเอกสารของแอปพลิเคชัน สามารถจัดทำดัชนีเพื่อให้มั่นใจว่าดัชนีกลางที่มีประสิทธิภาพ

เริ่มต้นใช้งาน AppSearch

ตัวอย่างในส่วนนี้จะแสดงวิธีใช้ AppSearch API เพื่อผสานรวม ด้วยแอปพลิเคชันจดโน้ตสมมติ

เขียนชั้นเรียนในเอกสาร

ขั้นตอนแรกในการผสานรวมกับ AppSearch คือการเขียนคลาสเอกสาร อธิบายข้อมูลที่จะแทรกลงในฐานข้อมูล ทำเครื่องหมายชั้นเรียนเป็นชั้นเรียนเอกสาร โดยใช้ @Document คำอธิบายประกอบ คุณสามารถใช้อินสแตนซ์ของคลาสเอกสารเพื่อใส่เอกสาร และ เรียกเอกสารจากฐานข้อมูล

โค้ดต่อไปนี้จะระบุคลาสเอกสาร Note ที่มี มีคำอธิบายประกอบ @Document.StringProperty แล้ว สำหรับจัดทำดัชนีข้อความของออบเจ็กต์หมายเหตุ

Kotlin

@Document
public data class Note(

    // Required field for a document class. All documents MUST have a namespace.
    @Document.Namespace
    val namespace: String,

    // Required field for a document class. All documents MUST have an Id.
    @Document.Id
    val id: String,

    // Optional field for a document class, used to set the score of the
    // document. If this is not included in a document class, the score is set
    // to a default of 0.
    @Document.Score
    val score: Int,

    // Optional field for a document class, used to index a note's text for this
    // document class.
    @Document.StringProperty(indexingType = AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
    val text: String
)

Java

@Document
public class Note {

  // Required field for a document class. All documents MUST have a namespace.
  @Document.Namespace
  private final String namespace;

  // Required field for a document class. All documents MUST have an Id.
  @Document.Id
  private final String id;

  // Optional field for a document class, used to set the score of the
  // document. If this is not included in a document class, the score is set
  // to a default of 0.
  @Document.Score
  private final int score;

  // Optional field for a document class, used to index a note's text for this
  // document class.
  @Document.StringProperty(indexingType = StringPropertyConfig.INDEXING_TYPE_PREFIXES)
  private final String text;

  Note(@NonNull String id, @NonNull String namespace, int score, @NonNull String text) {
    this.id = Objects.requireNonNull(id);
    this.namespace = Objects.requireNonNull(namespace);
    this.score = score;
    this.text = Objects.requireNonNull(text);
  }

  @NonNull
  public String getNamespace() {
    return namespace;
  }

  @NonNull
  public String getId() {
    return id;
  }

  public int getScore() {
    return score;
  }

  @NonNull
  public String getText() {
     return text;
  }
}

เปิดฐานข้อมูล

คุณต้องสร้างฐานข้อมูลก่อนที่จะทำงานกับเอกสาร รหัสต่อไปนี้ สร้างฐานข้อมูลใหม่ชื่อ notes_app และรับ ListenableFuture ในราคา AppSearchSession ซึ่งแสดงถึงการเชื่อมต่อกับฐานข้อมูล และให้ API สำหรับ การดำเนินงานฐานข้อมูล

Kotlin

val context: Context = getApplicationContext()
val sessionFuture = LocalStorage.createSearchSession(
    LocalStorage.SearchContext.Builder(context, /*databaseName=*/"notes_app")
    .build()
)

Java

Context context = getApplicationContext();
ListenableFuture<AppSearchSession> sessionFuture = LocalStorage.createSearchSession(
       new LocalStorage.SearchContext.Builder(context, /*databaseName=*/ "notes_app")
               .build()
);

ตั้งค่าสคีมา

คุณต้องตั้งค่าสคีมาก่อนจึงจะใส่เอกสารและเรียกข้อมูลได้ จากฐานข้อมูล สคีมาฐานข้อมูลประกอบด้วยประเภทต่างๆ ของข้อมูลที่มีโครงสร้าง ซึ่งเรียกว่า "ประเภทสคีมา" โค้ดต่อไปนี้ตั้งค่า โดยระบุคลาสเอกสารเป็นประเภทสคีมา

Kotlin

val setSchemaRequest = SetSchemaRequest.Builder().addDocumentClasses(Note::class.java)
    .build()
val setSchemaFuture = Futures.transformAsync(
    sessionFuture,
    { session ->
        session?.setSchema(setSchemaRequest)
    }, mExecutor
)

Java

SetSchemaRequest setSchemaRequest = new SetSchemaRequest.Builder().addDocumentClasses(Note.class)
       .build();
ListenableFuture<SetSchemaResponse> setSchemaFuture =
       Futures.transformAsync(sessionFuture, session -> session.setSchema(setSchemaRequest), mExecutor);

วางเอกสารในฐานข้อมูล

เมื่อเพิ่มประเภทสคีมาแล้ว คุณสามารถเพิ่มเอกสารประเภทนั้นลงในฐานข้อมูลได้ โค้ดต่อไปนี้จะสร้างเอกสารประเภทสคีมา Note โดยใช้ Note เครื่องมือสร้างคลาสของเอกสาร โดยจะตั้งค่าเนมสเปซ user1 ของเอกสารเพื่อแสดง ผู้ใช้ที่กำหนดเองของตัวอย่างนี้ จากนั้นเอกสารจะถูกแทรกในฐานข้อมูล และ Listener จะแนบไปด้วยเพื่อประมวลผลผลลัพธ์ของคำสั่ง Put

Kotlin

val note = Note(
    namespace="user1",
    id="noteId",
    score=10,
    text="Buy fresh fruit"
)

val putRequest = PutDocumentsRequest.Builder().addDocuments(note).build()
val putFuture = Futures.transformAsync(
    sessionFuture,
    { session ->
        session?.put(putRequest)
    }, mExecutor
)

Futures.addCallback(
    putFuture,
    object : FutureCallback<AppSearchBatchResult<String, Void>?> {
        override fun onSuccess(result: AppSearchBatchResult<String, Void>?) {

            // Gets map of successful results from Id to Void
            val successfulResults = result?.successes

            // Gets map of failed results from Id to AppSearchResult
            val failedResults = result?.failures
        }

        override fun onFailure(t: Throwable) {
            Log.e(TAG, "Failed to put documents.", t)
        }
    },
    mExecutor
)

Java

Note note = new Note(/*namespace=*/"user1", /*id=*/
                "noteId", /*score=*/ 10, /*text=*/ "Buy fresh fruit!");

PutDocumentsRequest putRequest = new PutDocumentsRequest.Builder().addDocuments(note)
       .build();
ListenableFuture<AppSearchBatchResult<String, Void>> putFuture =
       Futures.transformAsync(sessionFuture, session -> session.put(putRequest), mExecutor);

Futures.addCallback(putFuture, new FutureCallback<AppSearchBatchResult<String, Void>>() {
   @Override
   public void onSuccess(@Nullable AppSearchBatchResult<String, Void> result) {

     // Gets map of successful results from Id to Void
     Map<String, Void> successfulResults = result.getSuccesses();

     // Gets map of failed results from Id to AppSearchResult
     Map<String, AppSearchResult<Void>> failedResults = result.getFailures();
   }

   @Override
   public void onFailure(@NonNull Throwable t) {
      Log.e(TAG, "Failed to put documents.", t);
   }
}, mExecutor);

คุณสามารถค้นหาเอกสารที่มีการจัดทำดัชนีโดยใช้การดำเนินการค้นหาที่ครอบคลุมใน ส่วนนี้ โค้ดต่อไปนี้ดำเนินการค้นหาคำว่า "ผลไม้" ในช่วง ฐานข้อมูลสำหรับเอกสารที่อยู่ในเนมสเปซ user1

Kotlin

val searchSpec = SearchSpec.Builder()
    .addFilterNamespaces("user1")
    .build();

val searchFuture = Futures.transform(
    sessionFuture,
    { session ->
        session?.search("fruit", searchSpec)
    },
    mExecutor
)
Futures.addCallback(
    searchFuture,
    object : FutureCallback<SearchResults> {
        override fun onSuccess(searchResults: SearchResults?) {
            iterateSearchResults(searchResults)
        }

        override fun onFailure(t: Throwable?) {
            Log.e("TAG", "Failed to search notes in AppSearch.", t)
        }
    },
    mExecutor
)

Java

SearchSpec searchSpec = new SearchSpec.Builder()
       .addFilterNamespaces("user1")
       .build();

ListenableFuture<SearchResults> searchFuture =
       Futures.transform(sessionFuture, session -> session.search("fruit", searchSpec),
       mExecutor);

Futures.addCallback(searchFuture,
       new FutureCallback<SearchResults>() {
           @Override
           public void onSuccess(@Nullable SearchResults searchResults) {
               iterateSearchResults(searchResults);
           }

           @Override
           public void onFailure(@NonNull Throwable t) {
               Log.e(TAG, "Failed to search notes in AppSearch.", t);
           }
       }, mExecutor);

ทำซ้ำผ่านผลการค้นหา

การค้นหาจะแสดง SearchResults ซึ่งให้สิทธิ์เข้าถึงหน้าของออบเจ็กต์ SearchResult แต่ละSearchResult ตรงกับ GenericDocument ซึ่งเป็นรูปแบบทั่วไปของ ที่มีการแปลงเอกสารทั้งหมด โค้ดต่อไปนี้จะได้รับ หน้าผลการค้นหา และแปลงผลลัพธ์กลับไปเป็นเอกสาร Note

Kotlin

Futures.transform(
    searchResults?.nextPage,
    { page: List<SearchResult>? ->
        // Gets GenericDocument from SearchResult.
        val genericDocument: GenericDocument = page!![0].genericDocument
        val schemaType = genericDocument.schemaType
        val note: Note? = try {
            if (schemaType == "Note") {
                // Converts GenericDocument object to Note object.
                genericDocument.toDocumentClass(Note::class.java)
            } else null
        } catch (e: AppSearchException) {
            Log.e(
                TAG,
                "Failed to convert GenericDocument to Note",
                e
            )
            null
        }
        note
    },
    mExecutor
)

Java

Futures.transform(searchResults.getNextPage(), page -> {
  // Gets GenericDocument from SearchResult.
  GenericDocument genericDocument = page.get(0).getGenericDocument();
  String schemaType = genericDocument.getSchemaType();

  Note note = null;

  if (schemaType.equals("Note")) {
    try {
      // Converts GenericDocument object to Note object.
      note = genericDocument.toDocumentClass(Note.class);
    } catch (AppSearchException e) {
      Log.e(TAG, "Failed to convert GenericDocument to Note", e);
    }
  }

  return note;
}, mExecutor);

นำเอกสารออก

เมื่อผู้ใช้ลบโน้ต แอปพลิเคชันจะลบ Note ที่เกี่ยวข้อง จากฐานข้อมูล วิธีนี้ช่วยให้มั่นใจว่าบันทึกจะไม่ปรากฏใน การค้นหา โค้ดต่อไปนี้ส่งคำขออย่างชัดแจ้งให้นำ Note ออก จากฐานข้อมูลตามรหัส

Kotlin

val removeRequest = RemoveByDocumentIdRequest.Builder("user1")
    .addIds("noteId")
    .build()

val removeFuture = Futures.transformAsync(
    sessionFuture, { session ->
        session?.remove(removeRequest)
    },
    mExecutor
)

Java

RemoveByDocumentIdRequest removeRequest = new RemoveByDocumentIdRequest.Builder("user1")
       .addIds("noteId")
       .build();

ListenableFuture<AppSearchBatchResult<String, Void>> removeFuture =
       Futures.transformAsync(sessionFuture, session -> session.remove(removeRequest), mExecutor);

คงอยู่ในดิสก์

ควรอัปเดตฐานข้อมูลไปยังดิสก์เป็นระยะๆ โดยการเรียกใช้ requestFlush() การเรียกโค้ดต่อไปนี้ requestFlush() พร้อมกับ Listener เพื่อระบุว่าเป็นการโทร ประสบความสำเร็จ

Kotlin

val requestFlushFuture = Futures.transformAsync(
    sessionFuture,
    { session -> session?.requestFlush() }, mExecutor
)

Futures.addCallback(requestFlushFuture, object : FutureCallback<Void?> {
    override fun onSuccess(result: Void?) {
        // Success! Database updates have been persisted to disk.
    }

    override fun onFailure(t: Throwable) {
        Log.e(TAG, "Failed to flush database updates.", t)
    }
}, mExecutor)

Java

ListenableFuture<Void> requestFlushFuture = Futures.transformAsync(sessionFuture,
        session -> session.requestFlush(), mExecutor);

Futures.addCallback(requestFlushFuture, new FutureCallback<Void>() {
    @Override
    public void onSuccess(@Nullable Void result) {
        // Success! Database updates have been persisted to disk.
    }

    @Override
    public void onFailure(@NonNull Throwable t) {
        Log.e(TAG, "Failed to flush database updates.", t);
    }
}, mExecutor);

ปิดเซสชัน

AppSearchSession ควรปิดเมื่อแอปพลิเคชันจะไม่เรียกใช้ฐานข้อมูลใดๆ อีก การดำเนินงาน โค้ดต่อไปนี้จะปิดเซสชัน AppSearch ที่เปิดอยู่ ก่อนหน้านี้และยังคงอัปเดตดิสก์ทั้งหมด

Kotlin

val closeFuture = Futures.transform<AppSearchSession, Unit>(sessionFuture,
    { session ->
        session?.close()
        Unit
    }, mExecutor
)

Java

ListenableFuture<Void> closeFuture = Futures.transform(sessionFuture, session -> {
   session.close();
   return null;
}, mExecutor);

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับ AppSearch ได้ในแหล่งข้อมูลเพิ่มเติมต่อไปนี้

ตัวอย่าง

  • ตัวอย่าง Android AppSearch (Kotlin) แอปจดโน้ตที่ใช้ AppSearch เพื่อจัดทำดัชนีโน้ตของผู้ใช้ และช่วยให้ผู้ใช้ เพื่อค้นหาโน้ตของตนเอง

แสดงความคิดเห็น

แชร์ความคิดเห็นและไอเดียกับเราผ่านแหล่งข้อมูลเหล่านี้

เครื่องมือติดตามปัญหา

รายงานข้อบกพร่องเพื่อให้เราแก้ไขได้