كيفية تعليق الإخطار للمراقبين أثناء إجراء العديد من التغييرات باستخدام ContentProvider

StackOverflow https://stackoverflow.com/questions/4292182

سؤال

لديّ expressablistview يستخدم simpleCursorTreeadApter الذي يستخدم المؤشرات التي يتم إرجاعها بواسطة contentProvider. هذا جيد لأنه يمتاز دائمًا بالمزامنة مع البيانات ، لكن في بعض الأحيان أحتاج إلى إجراء العديد من التغييرات على قاعدة البيانات بحيث يتم طلب المؤشر عدة مرات في نفس الثانية. هل من الممكن تعليق إخطار محتوى المحتوى لتجنب القوالب غير الضرورية؟

هل كانت مفيدة؟

المحلول

يتمثل الحل المحتمل في تعديل مزود المحتوى للسماح بتعليق الإخطارات. تتم إضافة URIS لإخطارها إلى قائمة انتظار حتى يتم تعطيل التعليق.

private boolean suspendNotifications = false;
private LinkedList<Uri> suspendedNotifications = new LinkedList<Uri>();
private HashSet<Uri> suspendedNotificationsSet = new HashSet<Uri>();

    private void notifyChange(Uri uri) {
    if (suspendNotifications) {
        synchronized (suspendedNotificationsSet) { // Must be thread-safe
            if (suspendedNotificationsSet.contains(uri)) {
                // In case the URI is in the queue already, move it to the end.
                // This could lead to side effects because the order is changed
                // but we also reduce the number of outstanding notifications.
                suspendedNotifications.remove(uri); 
            }
            suspendedNotifications.add(uri);
            suspendedNotificationsSet.add(uri);
        }
    }
    else {
        getContext().getContentResolver().notifyChange(uri, null);
    }
}

private void notifyOutstandingChanges() {
    Uri uri;
    while ((uri = suspendedNotifications.poll()) != null) {
        getContext().getContentResolver().notifyChange(uri, null);
        suspendedNotificationsSet.remove(uri);
    }
}

private void setNotificationsSuspended(boolean suspended) {
    this.suspendNotifications = suspended;
    if (!suspended) notifyOutstandingChanges();
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    ...
    notifyChange(uri);
    return newItemUri;
}

لست متأكدًا من أفضل طريقة لتمكين/تعطيل التعليق ، لكن احتمال واحد هو أن يكون لديك URI خاص يعمل على تشغيل/إيقاف التعليق (على سبيل المثال المحتوى: //u003Cauthority> /تعليق) في الطريقة التحديث ():

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    switch (uriMatcher.match(uri)) {
    ...
    case SUSPEND:
        boolean enabled = values.getAsBoolean("enabled");
        setNotificationsSuspended(enabled);
        break;
    ... 
    }
}

يمكن للخدمة التي تقوم بالتغييرات في قاعدة البيانات الآن تعليق ContentProvider عندما تبدأ وتعطيل التعليق عند الانتهاء.

نصائح أخرى

هل تستطيع استعمال http://developer.android.com/Reference/android/widget/baseadapter.html#unregisterDatasetObserver(android.database.datasetobserver) لإلغاء تسجيل مستمعيك وبمجرد أن يصبح عملك جاهزًا ، قم بتسجيلهم مرة أخرى؟ يبدو وكأنه مصنوعة غير متزامنة بالنسبة لي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top