Search code examples
javarealm

Realm Async Task


I'm trying to use AsyncTransaction for inserting some object, but for the moment it is a failed...

I tried to debug, but without success either ...

See my code :

realm.executeTransactionAsync(
                 new Realm.Transaction() {
                    @Override
                    public void execute(@NonNull Realm realm) {
                        Log.i("Insert", "Insert start");
                        realm.insert(character);
                    }
                }, new Realm.Transaction.OnSuccess() {
                    @Override
                    public void onSuccess() {
                        Log.i("Insert", "Insert complete");
                        finish();
                    }
                }, new Realm.Transaction.OnError() {
                    @Override
                    public void onError(Throwable error) {
                        Log.i("Insert","Error " + error.getMessage());
                    }
                });

When i debug, i see that I didn't go on any callback of the async-transaction, there is no log, there is nothing that can help me.

Thank in advance,

EDIT :

public RealmAsyncTask executeTransactionAsync(final Transaction transaction,
        @Nullable final Realm.Transaction.OnSuccess onSuccess,
        @Nullable final Realm.Transaction.OnError onError) {
    checkIfValid();

    //noinspection ConstantConditions
    if (transaction == null) {
        throw new IllegalArgumentException("Transaction should not be null");
    }

    // Avoid to call canDeliverNotification() in bg thread.
    final boolean canDeliverNotification = sharedRealm.capabilities.canDeliverNotification();

    // If the user provided a Callback then we have to make sure the current Realm has an events looper to deliver
    // the results.
    if ((onSuccess != null || onError != null)) {
        sharedRealm.capabilities.checkCanDeliverNotification("Callback cannot be delivered on current thread.");
    }

    // We need to use the same configuration to open a background SharedRealm (i.e Realm)
    // to perform the transaction
    final RealmConfiguration realmConfiguration = getConfiguration();
    // We need to deliver the callback even if the Realm is closed. So acquire a reference to the notifier here.
    final RealmNotifier realmNotifier = sharedRealm.realmNotifier;

    final Future<?> pendingTransaction = asyncTaskExecutor.submitTransaction(new Runnable() {
        @Override
        public void run() {
            if (Thread.currentThread().isInterrupted()) {
                return;
            }

            SharedRealm.VersionID versionID = null;
            Throwable exception = null;

            final Realm bgRealm = Realm.getInstance(realmConfiguration);
            bgRealm.beginTransaction();

    // NOTHING IS DONE AFTER IS POINT .....
            try {
                transaction.execute(bgRealm);

                if (Thread.currentThread().isInterrupted()) {
                    return;
                }

                bgRealm.commitTransaction();
                // The bgRealm needs to be closed before post event to caller's handler to avoid concurrency
                // problem. This is currently guaranteed by posting callbacks later below.
                versionID = bgRealm.sharedRealm.getVersionID();
            } catch (final Throwable e) {
                exception = e;
            } finally {
                try {
                    if (bgRealm.isInTransaction()) {
                        bgRealm.cancelTransaction();
                    }
                } finally {
                    bgRealm.close();
                }
            }

            final Throwable backgroundException = exception;
            final SharedRealm.VersionID backgroundVersionID = versionID;
            // Cannot be interrupted anymore.
            if (canDeliverNotification) {
                if (backgroundVersionID != null && onSuccess != null) {
                    realmNotifier.post(new Runnable() {
                        @Override
                        public void run() {
                            if (isClosed()) {
                                // The caller Realm is closed. Just call the onSuccess. Since the new created Realm
                                // cannot be behind the background one.
                                onSuccess.onSuccess();
                                return;
                            }

                            if (sharedRealm.getVersionID().compareTo(backgroundVersionID) < 0) {
                                sharedRealm.realmNotifier.addTransactionCallback(new Runnable() {
                                    @Override
                                    public void run() {
                                        onSuccess.onSuccess();
                                    }
                                });
                            } else {
                                onSuccess.onSuccess();
                            }
                        }
                    });
                } else if (backgroundException != null) {
                    realmNotifier.post(new Runnable() {
                        @Override
                        public void run() {
                            if (onError != null) {
                                onError.onError(backgroundException);
                            } else {
                                throw new RealmException("Async transaction failed", backgroundException);
                            }
                        }
                    });
                }
            } else {
                if (backgroundException != null) {
                    // FIXME: ThreadPoolExecutor will never throw the exception in the background.
                    // We need a redesign of the async transaction API.
                    // Throw in the worker thread since the caller thread cannot get notifications.
                    throw new RealmException("Async transaction failed", backgroundException);
                }
            }

        }
    });

    return new RealmAsyncTaskImpl(pendingTransaction, asyncTaskExecutor);
}

Solution

  • I found the trick.

    In my constructor, i add some RealmObject to a another, that create a error

    (Can't not write on a non write transaction)

    The second point, was i used beginTransaction() on the parent, but it block on the other part for asynctransaction

    I change my code for using the RealmRecyclerView on the firstPart and i didn't have the problem anymore

    Thanks