Back to project page android-memento.
The source code is released under:
Apache License
If you think the Android project android-memento listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * android-memento-lib https://github.com/twofortyfouram/android-memento * Copyright 2014 two forty four a.m. LLC */*from w w w. j a v a 2s . co m*/ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package com.twofortyfouram.memento.provider; import com.twofortyfouram.log.Lumberjack; import com.twofortyfouram.spackle.util.bundle.BundleScrubber; import net.jcip.annotations.ThreadSafe; import android.app.IntentService; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.OperationApplicationException; import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.util.ArrayList; /** * Perform a series of {@link ContentProviderOperation}s in a background thread. * The primary use case is to simplify improving UI performance. For example, * when the user hits the back button in an Activity that wants to save some * data. Rather than blocking the Activity (which is necessary to ensure the * process has enough priority to complete the save to disk), this service * provides an alternative way to raise the process's priority without blocking * the main thread for the disk write. * <p> * To use, call either * {@link #applyBatchWithAlternativeAsynchronous(Context, String, ArrayList, ArrayList)} * or * {@link #applyBatchWithAlternativeSynchronous(Context, String, ArrayList, ArrayList)} * . */ @ThreadSafe public final class ContentProviderOperationService extends IntentService { /** * Type: {@code String}. * <p> * Authority for the operations to write. */ @NonNull private static final String EXTRA_STRING_AUTHORITY = ContentProviderOperationService.class .getName() + ".extra.STRING_AUTHORITY"; //$NON-NLS-1$ /** * Type: {@code ArrayList<ContentProviderOperation>}. * <p> * Set of Content Provider operations to apply. */ @NonNull private static final String EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_PRIMARY = ContentProviderOperationService.class .getName() + ".extra.PARCELABLE_ARRAY_LIST_OPERATIONS_PRIMARY"; //$NON-NLS-1$ /** * Type: {@code ArrayList<ContentProviderOperation>}. * <p> * Set of optional alternative Content Provider operations to apply if * {@link #EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_PRIMARY} fail. */ @NonNull private static final String EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_ALTERNATIVE = ContentProviderOperationService.class .getName() + ".extra.PARCELABLE_ARRAY_LIST_OPERATIONS_ALTERNATIVE"; //$NON-NLS-1$ /** * Construct a new ContentProviderService. */ public ContentProviderOperationService() { super(ContentProviderOperationService.class.getName()); /* * Redelivery is not desired, as that could cause duplicate * transactions. */ setIntentRedelivery(false); } @Override protected void onHandleIntent(@Nullable final Intent intent) { BundleScrubber.scrub(intent); Lumberjack.v("Received %s", intent); //$NON-NLS-1$ if (null != intent) { final String authority = intent.getStringExtra(EXTRA_STRING_AUTHORITY); final ArrayList<ContentProviderOperation> primaryOperations = intent .getParcelableArrayListExtra(EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_PRIMARY); final ArrayList<ContentProviderOperation> alternativeOperations = intent .getParcelableArrayListExtra( EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_ALTERNATIVE); applyBatchWithAlternativeSynchronous(getApplicationContext(), authority, primaryOperations, alternativeOperations); } } /** * Performs * {@link #applyBatchWithAlternativeSynchronous(Context, String, ArrayList, ArrayList)} * asynchronously. Operations are queued, so multiple calls to this method * are applied in the order that they were queued. * * @param context Application context. * @param authority Content Provider authority to use for all operations. * @param primaryOperations A set of operations to perform. * @param alternativeOperations A set of operations to perform if * {@code primaryOperations} fail. */ public static void applyBatchWithAlternativeAsynchronous(@NonNull final Context context, @NonNull final String authority, @NonNull final ArrayList<ContentProviderOperation> primaryOperations, @Nullable final ArrayList<ContentProviderOperation> alternativeOperations) { final Intent i = new Intent(context, ContentProviderOperationService.class); i.putExtra(EXTRA_STRING_AUTHORITY, authority); i.putExtra(EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_PRIMARY, primaryOperations); i.putExtra(EXTRA_PARCELABLE_ARRAY_LIST_OPERATIONS_ALTERNATIVE, alternativeOperations); context.startService(i); } /** * Synchronously applies a batch operation, with an alternative batch * operation if the first operation fails. * * @param context Application context. * @param authority Content Provider authority to use for all operations. * @param primaryOperations A set of operations to perform. * @param alternativeOperations A set of operations to perform if * {@code primaryOperations} fail. */ public static void applyBatchWithAlternativeSynchronous(@NonNull final Context context, @NonNull final String authority, @NonNull final ArrayList<ContentProviderOperation> primaryOperations, @Nullable final ArrayList<ContentProviderOperation> alternativeOperations) { final ContentResolver resolver = context.getContentResolver(); try { resolver.applyBatch(authority, primaryOperations); } catch (final OperationApplicationException e) { if (null != alternativeOperations) { /* * TODO: Ideally the primary and alternative operations would both occur in the same * transaction, rather than two separate transactions. This is impossible for * standard Android ContentProvider objects which do not guarantee applyBatch() is * atomic, but it might be possible if the provider is a local instance of * AbstractSqliteContentProvider. */ try { resolver.applyBatch(authority, alternativeOperations); } catch (final OperationApplicationException e2) { Lumberjack.e("Error occurred during ContentProviderOperation%s", e2); //$NON-NLS-1$ } catch (final RemoteException e2) { Lumberjack.e("Error occurred during ContentProviderOperation%s", e2); //$NON-NLS-1$ } } } catch (final RemoteException e) { Lumberjack.e("Error occurred during ContentProviderOperation%s", e); //$NON-NLS-1$ } } }