เรียกใช้อะแดปเตอร์การซิงค์

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

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

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

คุณมีตัวเลือกต่อไปนี้ในการเรียกใช้อะแดปเตอร์การซิงค์

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

ส่วนที่เหลือของบทเรียนนี้จะอธิบายตัวเลือกแต่ละข้ออย่างละเอียด

เรียกใช้อะแดปเตอร์การซิงค์เมื่อข้อมูลเซิร์ฟเวอร์มีการเปลี่ยนแปลง

หากแอปของคุณโอนข้อมูลจากเซิร์ฟเวอร์และข้อมูลของเซิร์ฟเวอร์มีการเปลี่ยนแปลงบ่อย คุณสามารถใช้ อะแดปเตอร์การซิงค์สำหรับดาวน์โหลดตามการเปลี่ยนแปลงของข้อมูล หากต้องการเรียกใช้อะแดปเตอร์การซิงค์ โปรดทำดังนี้ เซิร์ฟเวอร์จะส่งข้อความพิเศษไปยัง BroadcastReceiver ในแอปของคุณ ในการตอบกลับข้อความนี้ โปรดโทรติดต่อ ContentResolver.requestSync() เพื่อส่งสัญญาณเฟรมเวิร์กอะแดปเตอร์การซิงค์เพื่อเรียกใช้ อะแดปเตอร์การซิงค์

การรับส่งข้อความในระบบคลาวด์ของ Google (GCM) มอบทั้ง เซิร์ฟเวอร์และอุปกรณ์ที่จำเป็น เพื่อให้ระบบการรับส่งข้อความนี้ทำงานได้ การใช้ GCM เพื่อทริกเกอร์ การโอนจะมีความน่าเชื่อถือและมีประสิทธิภาพมากกว่าเซิร์ฟเวอร์แบบสำรวจสำหรับสถานะ ขณะทำแบบสำรวจ ต้องการ Service ที่มีการใช้งานเสมอ GCM จะใช้ BroadcastReceiver ที่เปิดใช้งานเมื่อมีข้อความมาถึง ขณะทำแบบสำรวจ ในช่วงเวลาที่สม่ำเสมอจะใช้พลังงานแบตเตอรี่แม้ว่าจะไม่มีการอัปเดต GCM จะส่ง ข้อความเมื่อจำเป็น

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

ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีเรียกใช้ requestSync() เพื่อตอบสนองต่อ ข้อความ GCM ขาเข้า:

Kotlin

...
// Constants
// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Account type
const val ACCOUNT_TYPE = "com.example.android.datasync"
// Account
const val ACCOUNT = "default_account"
// Incoming Intent key for extended data
const val KEY_SYNC_REQUEST = "com.example.android.datasync.KEY_SYNC_REQUEST"
...
class GcmBroadcastReceiver : BroadcastReceiver() {
    ...
    override fun onReceive(context: Context, intent: Intent) {
        // Get a GCM object instance
        val gcm: GoogleCloudMessaging = GoogleCloudMessaging.getInstance(context)
        // Get the type of GCM message
        val messageType: String? = gcm.getMessageType(intent)
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE == messageType
            && intent.getBooleanExtra(KEY_SYNC_REQUEST, false)) {
            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null)
            ...
        }
        ...
    }
    ...
}

Java

public class GcmBroadcastReceiver extends BroadcastReceiver {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Account type
    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
    // Account
    public static final String ACCOUNT = "default_account";
    // Incoming Intent key for extended data
    public static final String KEY_SYNC_REQUEST =
            "com.example.android.datasync.KEY_SYNC_REQUEST";
    ...
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get a GCM object instance
        GoogleCloudMessaging gcm =
                GoogleCloudMessaging.getInstance(context);
        // Get the type of GCM message
        String messageType = gcm.getMessageType(intent);
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)
            &&
            intent.getBooleanExtra(KEY_SYNC_REQUEST)) {
            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null);
            ...
        }
        ...
    }
    ...
}

เรียกใช้อะแดปเตอร์การซิงค์เมื่อข้อมูลของผู้ให้บริการเนื้อหามีการเปลี่ยนแปลง

หากแอปรวบรวมข้อมูลในผู้ให้บริการเนื้อหาและคุณต้องการอัปเดตเซิร์ฟเวอร์ทุกครั้ง เมื่ออัปเดตผู้ให้บริการ คุณจะตั้งค่าให้แอปเรียกใช้อะแดปเตอร์การซิงค์โดยอัตโนมัติได้ สิ่งต้องทำ หมายความว่าคุณลงทะเบียนผู้สังเกตการณ์สำหรับผู้ให้บริการเนื้อหา เมื่อข้อมูลในผู้ให้บริการเนื้อหา เปลี่ยนแปลงมากขึ้น กรอบโครงสร้างผู้ให้บริการเนื้อหาจึงเรียกผู้สังเกตการณ์ ในผู้สังเกตการณ์ เรียก requestSync()เพื่อบอกให้เฟรมเวิร์กทำงาน อะแดปเตอร์การซิงค์

หมายเหตุ: หากคุณใช้ผู้ให้บริการเนื้อหาสตับ คุณจะไม่มีข้อมูลใดๆ ใน ผู้ให้บริการเนื้อหาและ onChange() คือ ไม่เคยโทร ในกรณีนี้ คุณต้องมีกลไกของตนเองในการตรวจหาการเปลี่ยนแปลง ข้อมูลอุปกรณ์ กลไกนี้ยังทำหน้าที่เรียก requestSync() เมื่อข้อมูลเปลี่ยนแปลง

หากต้องการสร้างผู้สังเกตการณ์สำหรับผู้ให้บริการเนื้อหาของคุณ โปรดขยายชั้นเรียน ContentObserverและใช้รูปแบบทั้ง 2 รูปแบบ onChange() วิธี ใน onChange() โทร requestSync()เพื่อเริ่มอะแดปเตอร์การซิงค์

หากต้องการลงทะเบียนผู้สังเกตการณ์ ให้ส่งผ่านเป็นอาร์กิวเมนต์ในการเรียกไปยัง registerContentObserver() ใน การเรียกนี้คุณต้องส่งใน URI เนื้อหาสำหรับข้อมูลที่คุณต้องการดู เนื้อหา เฟรมเวิร์กของผู้ให้บริการจะเปรียบเทียบ URI นาฬิกานี้กับ URI เนื้อหาที่ส่งผ่านเป็นอาร์กิวเมนต์ของ ContentResolver วิธีที่จะแก้ไขผู้ให้บริการของคุณ เช่น ContentResolver.insert() หากมีชื่อที่ตรงกัน ระบบจะตั้ง การใช้งาน ContentObserver.onChange() จะถูกเรียก

ข้อมูลโค้ดต่อไปนี้แสดงวิธีกำหนด ContentObserver ที่เรียก requestSync() เมื่อโต๊ะ การเปลี่ยนแปลง:

Kotlin

// Constants
// Content provider scheme
const val SCHEME = "content://"
// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Path for the content provider table
const val TABLE_PATH = "data_table"
...
class MainActivity : FragmentActivity() {
    ...
    // A content URI for the content provider's data table
    private lateinit var uri: Uri
    // A content resolver for accessing the provider
    private lateinit var mResolver: ContentResolver
    ...
    inner class TableObserver(...) : ContentObserver(...) {
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         * This method signature is provided for compatibility with
         * older platforms.
         */
        override fun onChange(selfChange: Boolean) {
            /*
             * Invoke the method signature available as of
             * Android platform version 4.1, with a null URI.
             */
            onChange(selfChange, null)
        }

        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         */
        override fun onChange(selfChange: Boolean, changeUri: Uri?) {
            /*
             * Ask the framework to run your sync adapter.
             * To maintain backward compatibility, assume that
             * changeUri is null.
             */
            ContentResolver.requestSync(account, AUTHORITY, null)
        }
        ...
    }
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Get the content resolver object for your app
        mResolver = contentResolver
        // Construct a URI that points to the content provider data table
        uri = Uri.Builder()
                .scheme(SCHEME)
                .authority(AUTHORITY)
                .path(TABLE_PATH)
                .build()
        /*
         * Create a content observer object.
         * Its code does not mutate the provider, so set
         * selfChange to "false"
         */
        val observer = TableObserver(false)
        /*
         * Register the observer for the data table. The table's path
         * and any of its subpaths trigger the observer.
         */
        mResolver.registerContentObserver(uri, true, observer)
        ...
    }
    ...
}

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider scheme
    public static final String SCHEME = "content://";
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Path for the content provider table
    public static final String TABLE_PATH = "data_table";
    // Account
    public static final String ACCOUNT = "default_account";
    // Global variables
    // A content URI for the content provider's data table
    Uri uri;
    // A content resolver for accessing the provider
    ContentResolver mResolver;
    ...
    public class TableObserver extends ContentObserver {
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         * This method signature is provided for compatibility with
         * older platforms.
         */
        @Override
        public void onChange(boolean selfChange) {
            /*
             * Invoke the method signature available as of
             * Android platform version 4.1, with a null URI.
             */
            onChange(selfChange, null);
        }
        /*
         * Define a method that's called when data in the
         * observed content provider changes.
         */
        @Override
        public void onChange(boolean selfChange, Uri changeUri) {
            /*
             * Ask the framework to run your sync adapter.
             * To maintain backward compatibility, assume that
             * changeUri is null.
             */
            ContentResolver.requestSync(mAccount, AUTHORITY, null);
        }
        ...
    }
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Get the content resolver object for your app
        mResolver = getContentResolver();
        // Construct a URI that points to the content provider data table
        uri = new Uri.Builder()
                  .scheme(SCHEME)
                  .authority(AUTHORITY)
                  .path(TABLE_PATH)
                  .build();
        /*
         * Create a content observer object.
         * Its code does not mutate the provider, so set
         * selfChange to "false"
         */
        TableObserver observer = new TableObserver(false);
        /*
         * Register the observer for the data table. The table's path
         * and any of its subpaths trigger the observer.
         */
        mResolver.registerContentObserver(uri, true, observer);
        ...
    }
    ...
}

เรียกใช้อะแดปเตอร์การซิงค์เป็นระยะ

คุณสามารถเรียกใช้อะแดปเตอร์การซิงค์ได้เป็นระยะโดยกำหนดระยะเวลาที่ให้รอระหว่างการเรียกใช้ หรือโดยการเรียกใช้ในช่วงเวลาใดเวลาหนึ่งของวัน หรือทั้ง 2 อย่าง กำลังเรียกใช้อะแดปเตอร์การซิงค์ อนุญาตให้คุณกำหนดช่วงเวลาการอัปเดตของเซิร์ฟเวอร์อย่างคร่าวๆ ได้

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

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

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

โปรดสังเกตว่า addPeriodicSync() ไม่ ให้เรียกใช้อะแดปเตอร์การซิงค์ ณ เวลาใดเวลาหนึ่งของวัน เมื่อต้องการเรียกใช้อะแดปเตอร์การซิงค์ เวลาเดิมทุกวัน ใช้การปลุกซ้ำเป็นทริกเกอร์ มีคำอธิบายการปลุกซ้ำใน รายละเอียดในเอกสารประกอบอ้างอิงสำหรับ AlarmManager หากคุณใช้แท็ก เมธอด setInexactRepeating() ในการตั้งค่า ทริกเกอร์ช่วงเวลาของวันที่มีความเปลี่ยนแปลง คุณควรสุ่มเวลาเริ่มต้นเพื่อ ตรวจสอบว่าอะแดปเตอร์การซิงค์ทำงานจากอุปกรณ์ที่แตกต่างกันสลับกัน

เมธอด addPeriodicSync() ไม่ ปิดใช้ setSyncAutomatically() คุณจึงอาจต้องซิงค์หลายครั้งในระยะเวลาสั้นๆ นอกจากนี้ยังมีเพียงไม่กี่รายการ อนุญาตให้ใช้แฟล็กควบคุมอะแดปเตอร์การซิงค์ในการเรียกใช้ไปยัง addPeriodicSync(); แฟล็กที่ ไม่อนุญาตมีการอธิบายไว้ในเอกสารอ้างอิงสำหรับ addPeriodicSync()

ข้อมูลโค้ดต่อไปนี้แสดงวิธีตั้งเวลาให้อะแดปเตอร์ซิงค์เป็นระยะทำงาน

Kotlin

// Content provider authority
const val AUTHORITY = "com.example.android.datasync.provider"
// Account
const val ACCOUNT = "default_account"
// Sync interval constants
const val SECONDS_PER_MINUTE = 60L
const val SYNC_INTERVAL_IN_MINUTES = 60L
const val SYNC_INTERVAL = SYNC_INTERVAL_IN_MINUTES * SECONDS_PER_MINUTE
...
class MainActivity : FragmentActivity() {
    ...
    // A content resolver for accessing the provider
    private lateinit var mResolver: ContentResolver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Get the content resolver for your app
        mResolver = contentResolver
        /*
         * Turn on periodic syncing
         */
        ContentResolver.addPeriodicSync(
                mAccount,
                AUTHORITY,
                Bundle.EMPTY,
                SYNC_INTERVAL)
        ...
    }
    ...
}

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider";
    // Account
    public static final String ACCOUNT = "default_account";
    // Sync interval constants
    public static final long SECONDS_PER_MINUTE = 60L;
    public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
    public static final long SYNC_INTERVAL =
            SYNC_INTERVAL_IN_MINUTES *
            SECONDS_PER_MINUTE;
    // Global variables
    // A content resolver for accessing the provider
    ContentResolver mResolver;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Get the content resolver for your app
        mResolver = getContentResolver();
        /*
         * Turn on periodic syncing
         */
        ContentResolver.addPeriodicSync(
                mAccount,
                AUTHORITY,
                Bundle.EMPTY,
                SYNC_INTERVAL);
        ...
    }
    ...
}

เรียกใช้อะแดปเตอร์การซิงค์ตามคำขอ

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

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

แต่หากคุณยังต้องการเรียกใช้อะแดปเตอร์การซิงค์ตามคำขอ ให้ตั้งค่าสถานะอะแดปเตอร์การซิงค์สำหรับ เรียกใช้อะแดปเตอร์การซิงค์ด้วยตนเอง แล้วโทร ContentResolver.requestSync()

เรียกใช้การโอนแบบออนดีมานด์ที่มีแฟล็กต่อไปนี้

SYNC_EXTRAS_MANUAL
บังคับให้ซิงค์ด้วยตนเอง เฟรมเวิร์กอะแดปเตอร์การซิงค์จะไม่สนใจการตั้งค่าที่มีอยู่ เช่น ธงที่กำหนดโดย setSyncAutomatically()
SYNC_EXTRAS_EXPEDITED
บังคับให้เริ่มการซิงค์ทันที หากคุณไม่ตั้งค่านี้ ระบบอาจรอ วินาทีก่อนเรียกใช้คำขอซิงค์ เนื่องจากพยายามเพิ่มประสิทธิภาพการใช้งานแบตเตอรี่โดย โดยการกำหนดให้ส่งคำขอจำนวนมากในระยะเวลาสั้นๆ

ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีเรียก requestSync() ในการตอบกลับปุ่ม คลิก:

Kotlin

// Constants
// Content provider authority
val AUTHORITY = "com.example.android.datasync.provider"
// Account type
val ACCOUNT_TYPE = "com.example.android.datasync"
// Account
val ACCOUNT = "default_account"
...
class MainActivity : FragmentActivity() {
    ...
    // Instance fields
    private lateinit var mAccount: Account
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        /*
         * Create the placeholder account. The code for CreateSyncAccount
         * is listed in the lesson Creating a Sync Adapter
         */

        mAccount = createSyncAccount()
        ...
    }

    /**
     * Respond to a button click by calling requestSync(). This is an
     * asynchronous operation.
     *
     * This method is attached to the refresh button in the layout
     * XML file
     *
     * @param v The View associated with the method call,
     * in this case a Button
     */
    fun onRefreshButtonClick(v: View) {
        // Pass the settings flags by inserting them in a bundle
        val settingsBundle = Bundle().apply {
            putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true)
            putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true)
        }
        /*
         * Request the sync for the default account, authority, and
         * manual sync settings
         */
        ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle)
    }

Java

public class MainActivity extends FragmentActivity {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY =
            "com.example.android.datasync.provider";
    // Account type
    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
    // Account
    public static final String ACCOUNT = "default_account";
    // Instance fields
    Account mAccount;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        /*
         * Create the placeholder account. The code for CreateSyncAccount
         * is listed in the lesson Creating a Sync Adapter
         */

        mAccount = CreateSyncAccount(this);
        ...
    }
    /**
     * Respond to a button click by calling requestSync(). This is an
     * asynchronous operation.
     *
     * This method is attached to the refresh button in the layout
     * XML file
     *
     * @param v The View associated with the method call,
     * in this case a Button
     */
    public void onRefreshButtonClick(View v) {
        // Pass the settings flags by inserting them in a bundle
        Bundle settingsBundle = new Bundle();
        settingsBundle.putBoolean(
                ContentResolver.SYNC_EXTRAS_MANUAL, true);
        settingsBundle.putBoolean(
                ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
        /*
         * Request the sync for the default account, authority, and
         * manual sync settings
         */
        ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);
    }