Search in sources :

Example 1 with Continuation

use of com.parse.boltsinternal.Continuation in project Parse-SDK-Android by ParsePlatform.

the class OfflineStore method fetchLocallyAsync.

/**
 * Gets the data for the given object from the offline database. Returns a task that will be
 * completed if data for the object was available. If the object is not in the cache, the task
 * will be faulted, with a CACHE_MISS error.
 *
 * @param object The object to fetch.
 * @param db A database connection to use.
 */
/* package for OfflineQueryLogic */
<T extends ParseObject> Task<T> fetchLocallyAsync(final T object, final ParseSQLiteDatabase db) {
    final TaskCompletionSource<T> tcs = new TaskCompletionSource<>();
    Task<String> uuidTask;
    synchronized (lock) {
        if (fetchedObjects.containsKey(object)) {
            // noinspection unchecked
            return (Task<T>) fetchedObjects.get(object);
        }
        /*
             * Put a placeholder so that anyone else who attempts to fetch this object will just wait for
             * this call to finish doing it.
             */
        // noinspection unchecked
        fetchedObjects.put(object, (Task<ParseObject>) tcs.getTask());
        uuidTask = objectToUuidMap.get(object);
    }
    String className = object.getClassName();
    String objectId = object.getObjectId();
    /*
         * If this gets set, then it will contain data from the offline store that needs to be merged
         * into the existing object in memory.
         */
    Task<String> jsonStringTask = Task.forResult(null);
    if (objectId == null) {
        // This Object has never been saved to Parse.
        if (uuidTask == null) {
        /*
                 * This object was not pulled from the data store or previously saved to it, so there's
                 * nothing that can be fetched from it. This isn't an error, because it's really convenient
                 * to try to fetch objects from the offline store just to make sure they are up-to-date, and
                 * we shouldn't force developers to specially handle this case.
                 */
        } else {
            /*
                 * This object is a new ParseObject that is known to the data store, but hasn't been
                 * fetched. The only way this could happen is if the object had previously been stored in
                 * the offline store, then the object was removed from memory (maybe by rebooting), and then
                 * a object with a pointer to it was fetched, so we only created the pointer. We need to
                 * pull the data out of the database using the UUID.
                 */
            final String[] select = { OfflineSQLiteOpenHelper.KEY_JSON };
            final String where = OfflineSQLiteOpenHelper.KEY_UUID + " = ?";
            final Capture<String> uuid = new Capture<>();
            jsonStringTask = uuidTask.onSuccessTask(task -> {
                uuid.set(task.getResult());
                String[] args = { uuid.get() };
                return db.queryAsync(OfflineSQLiteOpenHelper.TABLE_OBJECTS, select, where, args);
            }).onSuccess(task -> {
                Cursor cursor = task.getResult();
                cursor.moveToFirst();
                if (cursor.isAfterLast()) {
                    cursor.close();
                    throw new IllegalStateException("Attempted to find non-existent uuid " + uuid.get());
                }
                String json = cursor.getString(0);
                cursor.close();
                return json;
            });
        }
    } else {
        if (uuidTask != null) {
            /*
                 * This object is an existing ParseObject, and we must've already pulled its data out of the
                 * offline store, or else we wouldn't know its UUID. This should never happen.
                 */
            tcs.setError(new IllegalStateException("This object must have already been " + "fetched from the local datastore, but isn't marked as fetched."));
            synchronized (lock) {
                // Forget we even tried to fetch this object, so that retries will actually...
                // retry.
                fetchedObjects.remove(object);
            }
            return tcs.getTask();
        }
        /*
             * We've got a pointer to an existing ParseObject, but we've never pulled its data out of the
             * offline store. Since fetching from the server forces a fetch from the offline store, that
             * means this is a pointer. We need to try to find any existing entry for this object in the
             * database.
             */
        String[] select = { OfflineSQLiteOpenHelper.KEY_JSON, OfflineSQLiteOpenHelper.KEY_UUID };
        String where = String.format("%s = ? AND %s = ?", OfflineSQLiteOpenHelper.KEY_CLASS_NAME, OfflineSQLiteOpenHelper.KEY_OBJECT_ID);
        String[] args = { className, objectId };
        jsonStringTask = db.queryAsync(OfflineSQLiteOpenHelper.TABLE_OBJECTS, select, where, args).onSuccess(task -> {
            Cursor cursor = task.getResult();
            cursor.moveToFirst();
            if (cursor.isAfterLast()) {
                /*
                                             * This is a pointer that came from Parse that references an object that has
                                             * never been saved in the offline store before. This just means there's no data
                                             * in the store that needs to be merged into the object.
                                             */
                cursor.close();
                throw new ParseException(ParseException.CACHE_MISS, "This object is not available in the offline cache.");
            }
            // we should fetch its data and record its UUID for future
            // reference.
            String jsonString = cursor.getString(0);
            String newUUID = cursor.getString(1);
            cursor.close();
            synchronized (lock) {
                /*
                                             * It's okay to put this object into the uuid map. No one will try to fetch
                                             * it, because it's already in the fetchedObjects map. And no one will try to
                                             * save to it without fetching it first, so everything should be just fine.
                                             */
                objectToUuidMap.put(object, Task.forResult(newUUID));
                uuidToObjectMap.put(newUUID, object);
            }
            return jsonString;
        });
    }
    return jsonStringTask.onSuccessTask((Continuation<String, Task<Void>>) task -> {
        String jsonString = task.getResult();
        if (jsonString == null) {
            return Task.forError(new ParseException(ParseException.CACHE_MISS, "Attempted to fetch an object offline which was never saved to the offline cache."));
        }
        final JSONObject json;
        try {
            json = new JSONObject(jsonString);
        } catch (JSONException e) {
            return Task.forError(e);
        }
        final Map<String, Task<ParseObject>> offlineObjects = new HashMap<>();
        (new ParseTraverser() {

            @Override
            protected boolean visit(Object object1) {
                if (object1 instanceof JSONObject && ((JSONObject) object1).optString("__type").equals("OfflineObject")) {
                    String uuid = ((JSONObject) object1).optString("uuid");
                    offlineObjects.put(uuid, getPointerAsync(uuid, db));
                }
                return true;
            }
        }).setTraverseParseObjects(false).setYieldRoot(false).traverse(json);
        return Task.whenAll(offlineObjects.values()).onSuccess(task1 -> {
            object.mergeREST(object.getState(), json, new OfflineDecoder(offlineObjects));
            return null;
        });
    }).continueWithTask(task -> {
        if (task.isCancelled()) {
            tcs.setCancelled();
        } else if (task.isFaulted()) {
            tcs.setError(task.getError());
        } else {
            tcs.setResult(object);
        }
        return tcs.getTask();
    });
}
Also used : Context(android.content.Context) Arrays(java.util.Arrays) ConstraintMatcher(com.parse.OfflineQueryLogic.ConstraintMatcher) Pair(android.util.Pair) TextUtils(android.text.TextUtils) HashMap(java.util.HashMap) UUID(java.util.UUID) ArrayList(java.util.ArrayList) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) List(java.util.List) JSONException(org.json.JSONException) Capture(com.parse.boltsinternal.Capture) Continuation(com.parse.boltsinternal.Continuation) JSONObject(org.json.JSONObject) Map(java.util.Map) ContentValues(android.content.ContentValues) LinkedList(java.util.LinkedList) Task(com.parse.boltsinternal.Task) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) WeakHashMap(java.util.WeakHashMap) Cursor(android.database.Cursor) Task(com.parse.boltsinternal.Task) Continuation(com.parse.boltsinternal.Continuation) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) JSONException(org.json.JSONException) Cursor(android.database.Cursor) Capture(com.parse.boltsinternal.Capture) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) JSONObject(org.json.JSONObject) JSONObject(org.json.JSONObject)

Example 2 with Continuation

use of com.parse.boltsinternal.Continuation in project Parse-SDK-Android by ParsePlatform.

the class Parse method initialize.

static void initialize(Configuration configuration, ParsePlugins parsePlugins) {
    if (isInitialized()) {
        PLog.w(TAG, "Parse is already initialized");
        return;
    }
    // NOTE (richardross): We will need this here, as ParsePlugins uses the return value of
    // isLocalDataStoreEnabled() to perform additional behavior.
    isLocalDatastoreEnabled = configuration.localDataStoreEnabled;
    allowCustomObjectId = configuration.allowCustomObjectId;
    if (parsePlugins == null) {
        ParsePlugins.initialize(configuration.context, configuration);
    } else {
        ParsePlugins.set(parsePlugins);
    }
    try {
        ParseRESTCommand.server = new URL(configuration.server);
    } catch (MalformedURLException ex) {
        throw new RuntimeException(ex);
    }
    ParseObject.registerParseSubclasses();
    if (configuration.localDataStoreEnabled) {
        offlineStore = new OfflineStore(configuration.context);
    } else {
        ParseKeyValueCache.initialize(configuration.context);
    }
    // Make sure the data on disk for Parse is for the current
    // application.
    checkCacheApplicationId();
    final Context context = configuration.context;
    Task.callInBackground((Callable<Void>) () -> {
        getEventuallyQueue(context);
        return null;
    });
    ParseFieldOperations.registerDefaultDecoders();
    if (!allParsePushIntentReceiversInternal()) {
        throw new SecurityException("To prevent external tampering to your app's notifications, " + "all receivers registered to handle the following actions must have " + "their exported attributes set to false: com.parse.push.intent.RECEIVE, " + "com.parse.push.intent.OPEN, com.parse.push.intent.DELETE");
    }
    ParseUser.getCurrentUserAsync().makeVoid().continueWith((Continuation<Void, Void>) task -> {
        ParseConfig.getCurrentConfig();
        return null;
    }, Task.BACKGROUND_EXECUTOR);
    dispatchOnParseInitialized();
    // FYI we probably don't want to do this if we ever add other callbacks.
    synchronized (MUTEX_CALLBACKS) {
        Parse.callbacks = null;
    }
}
Also used : Context(android.content.Context) Context(android.content.Context) RandomAccessFile(java.io.RandomAccessFile) PackageManager(android.content.pm.PackageManager) MalformedURLException(java.net.MalformedURLException) NonNull(androidx.annotation.NonNull) URL(java.net.URL) FileOutputStream(java.io.FileOutputStream) Set(java.util.Set) IOException(java.io.IOException) Callable(java.util.concurrent.Callable) File(java.io.File) ResolveInfo(android.content.pm.ResolveInfo) HashSet(java.util.HashSet) List(java.util.List) Nullable(androidx.annotation.Nullable) Continuation(com.parse.boltsinternal.Continuation) OkHttpClient(okhttp3.OkHttpClient) Task(com.parse.boltsinternal.Task) Log(android.util.Log) MalformedURLException(java.net.MalformedURLException) URL(java.net.URL)

Example 3 with Continuation

use of com.parse.boltsinternal.Continuation in project Parse-SDK-Android by ParsePlatform.

the class ParseRequest method executeAsync.

private Task<Response> executeAsync(final ParseHttpClient client, final ParseHttpRequest request, final int attemptsMade, final long delay, final ProgressCallback downloadProgressCallback, final Task<Void> cancellationToken) {
    if (cancellationToken != null && cancellationToken.isCancelled()) {
        return Task.cancelled();
    }
    return sendOneRequestAsync(client, request, downloadProgressCallback).continueWithTask(task -> {
        Exception e = task.getError();
        if (task.isFaulted() && e instanceof ParseException) {
            if (cancellationToken != null && cancellationToken.isCancelled()) {
                return Task.cancelled();
            }
            if (e instanceof ParseRequestException && ((ParseRequestException) e).isPermanentFailure) {
                return task;
            }
            if (attemptsMade < maxRetries()) {
                PLog.i("com.parse.ParseRequest", "Request failed. Waiting " + delay + " milliseconds before attempt #" + (attemptsMade + 1));
                final TaskCompletionSource<Response> retryTask = new TaskCompletionSource<>();
                ParseExecutors.scheduled().schedule(() -> {
                    executeAsync(client, request, attemptsMade + 1, delay * 2, downloadProgressCallback, cancellationToken).continueWithTask((Continuation<Response, Task<Void>>) task1 -> {
                        if (task1.isCancelled()) {
                            retryTask.setCancelled();
                        } else if (task1.isFaulted()) {
                            retryTask.setError(task1.getError());
                        } else {
                            retryTask.setResult(task1.getResult());
                        }
                        return null;
                    });
                }, delay, TimeUnit.MILLISECONDS);
                return retryTask.getTask();
            }
        }
        return task;
    });
}
Also used : ParseHttpResponse(com.parse.http.ParseHttpResponse) ParseHttpRequest(com.parse.http.ParseHttpRequest) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) NonNull(androidx.annotation.NonNull) IOException(java.io.IOException) BlockingQueue(java.util.concurrent.BlockingQueue) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) TimeUnit(java.util.concurrent.TimeUnit) ParseHttpBody(com.parse.http.ParseHttpBody) Continuation(com.parse.boltsinternal.Continuation) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ThreadFactory(java.util.concurrent.ThreadFactory) Task(com.parse.boltsinternal.Task) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) ParseHttpResponse(com.parse.http.ParseHttpResponse) ExecutorService(java.util.concurrent.ExecutorService) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) Task(com.parse.boltsinternal.Task) IOException(java.io.IOException)

Example 4 with Continuation

use of com.parse.boltsinternal.Continuation in project Parse-SDK-Android by ParsePlatform.

the class ParseUserTest method testSaveEventuallyWhenServerError.

// region testSaveEventuallyWhenServerError
@Test
public void testSaveEventuallyWhenServerError() throws Exception {
    Shadows.shadowOf(RuntimeEnvironment.application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE);
    Parse.Configuration configuration = new Parse.Configuration.Builder(RuntimeEnvironment.application).applicationId(BuildConfig.LIBRARY_PACKAGE_NAME).server("https://api.parse.com/1").enableLocalDataStore().build();
    ParsePlugins plugins = ParseTestUtils.mockParsePlugins(configuration);
    JSONObject mockResponse = new JSONObject();
    mockResponse.put("objectId", "objectId");
    mockResponse.put("email", "email@parse.com");
    mockResponse.put("username", "username");
    mockResponse.put("sessionToken", "r:sessionToken");
    mockResponse.put("createdAt", ParseDateFormat.getInstance().format(new Date(1000)));
    mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(2000)));
    ParseHttpClient restClient = ParseTestUtils.mockParseHttpClientWithResponse(mockResponse, 200, "OK");
    when(plugins.restClient()).thenReturn(restClient);
    Parse.initialize(configuration, plugins);
    ParseUser user = ParseUser.logIn("username", "password");
    assertFalse(user.isDirty());
    user.put("field", "data");
    assertTrue(user.isDirty());
    mockResponse = new JSONObject();
    mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(3000)));
    ParseTestUtils.updateMockParseHttpClientWithResponse(restClient, mockResponse, 200, "OK");
    final CountDownLatch saveCountDown1 = new CountDownLatch(1);
    final Capture<Exception> exceptionCapture = new Capture<>();
    user.saveInBackground().continueWith((Continuation<Void, Void>) task -> {
        exceptionCapture.set(task.getError());
        saveCountDown1.countDown();
        return null;
    });
    assertTrue(saveCountDown1.await(5, TimeUnit.SECONDS));
    assertNull(exceptionCapture.get());
    assertFalse(user.isDirty());
    user.put("field", "other data");
    assertTrue(user.isDirty());
    mockResponse = new JSONObject();
    mockResponse.put("error", "Save is not allowed");
    mockResponse.put("code", 141);
    ParseTestUtils.updateMockParseHttpClientWithResponse(restClient, mockResponse, 400, "Bad Request");
    final CountDownLatch saveEventuallyCountDown = new CountDownLatch(1);
    user.saveEventually().continueWith((Continuation<Void, Void>) task -> {
        exceptionCapture.set(task.getError());
        saveEventuallyCountDown.countDown();
        return null;
    });
    assertTrue(saveEventuallyCountDown.await(5, TimeUnit.SECONDS));
    assertTrue(exceptionCapture.get() instanceof ParseException);
    assertEquals(ParseException.SCRIPT_ERROR, ((ParseException) exceptionCapture.get()).getCode());
    assertEquals("Save is not allowed", exceptionCapture.get().getMessage());
    assertTrue(user.isDirty());
    // Simulate reboot
    Parse.destroy();
    Parse.initialize(configuration, plugins);
    user = ParseUser.getCurrentUser();
    assertTrue(user.isDirty());
    assertEquals("other data", user.get("field"));
    user.put("field", "another data");
    mockResponse = new JSONObject();
    mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(4000)));
    ParseTestUtils.updateMockParseHttpClientWithResponse(restClient, mockResponse, 200, "OK");
    final CountDownLatch saveCountDown2 = new CountDownLatch(1);
    user.saveInBackground().continueWith((Continuation<Void, Void>) task -> {
        exceptionCapture.set(task.getError());
        saveCountDown2.countDown();
        return null;
    });
    assertTrue(saveCountDown2.await(5, TimeUnit.SECONDS));
    assertNull(exceptionCapture.get());
    assertFalse(user.isDirty());
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Shadows(org.robolectric.Shadows) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ArgumentMatchers.nullable(org.mockito.ArgumentMatchers.nullable) Date(java.util.Date) Assert.assertNotSame(org.junit.Assert.assertNotSame) RunWith(org.junit.runner.RunWith) ArgumentMatchers.anyMap(org.mockito.ArgumentMatchers.anyMap) HashMap(java.util.HashMap) ArgumentMatchers.anyBoolean(org.mockito.ArgumentMatchers.anyBoolean) Mockito.spy(org.mockito.Mockito.spy) Parcel(android.os.Parcel) ShadowLooper.shadowMainLooper(org.robolectric.shadows.ShadowLooper.shadowMainLooper) Assert.assertSame(org.junit.Assert.assertSame) Manifest(android.Manifest) Capture(com.parse.boltsinternal.Capture) Continuation(com.parse.boltsinternal.Continuation) JSONObject(org.json.JSONObject) ArgumentCaptor(org.mockito.ArgumentCaptor) Mockito.verifyNoMoreInteractions(org.mockito.Mockito.verifyNoMoreInteractions) Map(java.util.Map) After(org.junit.After) Mockito.doReturn(org.mockito.Mockito.doReturn) ExpectedException(org.junit.rules.ExpectedException) Before(org.junit.Before) PAUSED(org.robolectric.annotation.LooperMode.Mode.PAUSED) Semaphore(java.util.concurrent.Semaphore) Assert.assertTrue(org.junit.Assert.assertTrue) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) LooperMode(org.robolectric.annotation.LooperMode) Mockito.when(org.mockito.Mockito.when) RuntimeEnvironment(org.robolectric.RuntimeEnvironment) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) RobolectricTestRunner(org.robolectric.RobolectricTestRunner) CountDownLatch(java.util.concurrent.CountDownLatch) Mockito.never(org.mockito.Mockito.never) Assert.assertNull(org.junit.Assert.assertNull) Rule(org.junit.Rule) Assert.assertFalse(org.junit.Assert.assertFalse) Task(com.parse.boltsinternal.Task) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) CountDownLatch(java.util.concurrent.CountDownLatch) Date(java.util.Date) ExpectedException(org.junit.rules.ExpectedException) Capture(com.parse.boltsinternal.Capture) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Example 5 with Continuation

use of com.parse.boltsinternal.Continuation in project Parse-SDK-Android by ParsePlatform.

the class ParseRESTObjectBatchCommand method executeBatch.

public static List<Task<JSONObject>> executeBatch(ParseHttpClient client, List<ParseRESTObjectCommand> commands, String sessionToken) {
    final int batchSize = commands.size();
    List<Task<JSONObject>> tasks = new ArrayList<>(batchSize);
    if (batchSize == 1) {
        // There's only one, just execute it
        tasks.add(commands.get(0).executeAsync(client));
        return tasks;
    }
    if (batchSize > COMMAND_OBJECT_BATCH_MAX_SIZE) {
        // There's more than the max, split it up into batches
        List<List<ParseRESTObjectCommand>> batches = Lists.partition(commands, COMMAND_OBJECT_BATCH_MAX_SIZE);
        for (int i = 0, size = batches.size(); i < size; i++) {
            List<ParseRESTObjectCommand> batch = batches.get(i);
            tasks.addAll(executeBatch(client, batch, sessionToken));
        }
        return tasks;
    }
    final List<TaskCompletionSource<JSONObject>> tcss = new ArrayList<>(batchSize);
    for (int i = 0; i < batchSize; i++) {
        TaskCompletionSource<JSONObject> tcs = new TaskCompletionSource<>();
        tcss.add(tcs);
        tasks.add(tcs.getTask());
    }
    JSONObject parameters = new JSONObject();
    JSONArray requests = new JSONArray();
    try {
        for (ParseRESTObjectCommand command : commands) {
            JSONObject requestParameters = new JSONObject();
            requestParameters.put("method", command.method.toString());
            requestParameters.put("path", new URL(server, command.httpPath).getPath());
            JSONObject body = command.jsonParameters;
            if (body != null) {
                requestParameters.put("body", body);
            }
            requests.put(requestParameters);
        }
        parameters.put("requests", requests);
    } catch (JSONException | MalformedURLException e) {
        throw new RuntimeException(e);
    }
    ParseRESTCommand command = new ParseRESTObjectBatchCommand("batch", ParseHttpRequest.Method.POST, parameters, sessionToken);
    command.executeAsync(client).continueWith((Continuation<JSONObject, Void>) task -> {
        TaskCompletionSource<JSONObject> tcs;
        if (task.isFaulted() || task.isCancelled()) {
            for (int i = 0; i < batchSize; i++) {
                tcs = tcss.get(i);
                if (task.isFaulted()) {
                    tcs.setError(task.getError());
                } else {
                    tcs.setCancelled();
                }
            }
        }
        JSONObject json = task.getResult();
        JSONArray results = json.getJSONArray(KEY_RESULTS);
        int resultLength = results.length();
        if (resultLength != batchSize) {
            for (int i = 0; i < batchSize; i++) {
                tcs = tcss.get(i);
                tcs.setError(new IllegalStateException("Batch command result count expected: " + batchSize + " but was: " + resultLength));
            }
        }
        for (int i = 0; i < batchSize; i++) {
            JSONObject result = results.getJSONObject(i);
            tcs = tcss.get(i);
            if (result.has("success")) {
                JSONObject success = result.getJSONObject("success");
                tcs.setResult(success);
            } else if (result.has("error")) {
                JSONObject error = result.getJSONObject("error");
                tcs.setError(new ParseException(error.getInt("code"), error.getString("error")));
            }
        }
        return null;
    });
    return tasks;
}
Also used : ParseHttpRequest(com.parse.http.ParseHttpRequest) MalformedURLException(java.net.MalformedURLException) URL(java.net.URL) IOException(java.io.IOException) ArrayList(java.util.ArrayList) List(java.util.List) JSONException(org.json.JSONException) Continuation(com.parse.boltsinternal.Continuation) JSONObject(org.json.JSONObject) Task(com.parse.boltsinternal.Task) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) ParseHttpResponse(com.parse.http.ParseHttpResponse) JSONArray(org.json.JSONArray) InputStream(java.io.InputStream) Task(com.parse.boltsinternal.Task) MalformedURLException(java.net.MalformedURLException) ArrayList(java.util.ArrayList) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) URL(java.net.URL) TaskCompletionSource(com.parse.boltsinternal.TaskCompletionSource) JSONObject(org.json.JSONObject) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

Continuation (com.parse.boltsinternal.Continuation)6 Task (com.parse.boltsinternal.Task)6 TaskCompletionSource (com.parse.boltsinternal.TaskCompletionSource)4 List (java.util.List)4 Context (android.content.Context)3 Capture (com.parse.boltsinternal.Capture)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 JSONObject (org.json.JSONObject)3 ContentValues (android.content.ContentValues)2 Cursor (android.database.Cursor)2 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)2 TextUtils (android.text.TextUtils)2 Pair (android.util.Pair)2 NonNull (androidx.annotation.NonNull)2 ConstraintMatcher (com.parse.OfflineQueryLogic.ConstraintMatcher)2 ParseHttpRequest (com.parse.http.ParseHttpRequest)2 ParseHttpResponse (com.parse.http.ParseHttpResponse)2