Как повлиять на представление в активности Android на основе результатов транзакции Firebase - PullRequest
0 голосов
/ 23 мая 2018

В моей деятельности есть следующая транзакция Firebase:

private void onRoomAccept(DatabaseReference thisRoomRef) {
        thisRoomRef.runTransaction(new Transaction.Handler() {
            @Override
            public Transaction.Result doTransaction(MutableData mutableData) {
                Room r = mutableData.getValue(Room.class);

                if (r != null && r.State.equals("Open")) {

                    r.Tutor = UserID;
                    r.State = "Live";

                    // Set value and report transaction success
                    mutableData.setValue(r);
                    return Transaction.success(mutableData);

                } else if (r == null || r.State.equals("Live")){
                    Intent intent3 = new Intent(TutorChatActivity.this, TutorActivity.class);
                    startActivity(intent3);
                }
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

Это прекрасно работает.Тем не менее, я хочу построить некоторые изменения представления поверх него.Например, если транзакция прошла успешно (это означает, что в базе данных установлено обновленное значение 'r'), я хочу изменить видимость кнопки.

В транзакцию было добавлено следующее, чтобы вызвать дальнейшую ошибку:

Positive.setVisibility(View.INVISIBLE);
Negative.setVisibility(View.INVISIBLE);

Аналогичным образом, для неудачного результата я хочу сделать всплывающее диалоговое окно, сообщающее, что произошла ошибкаперед тем, как вернуть пользователя обратно, в этом случае TutorActivity.

Я попытался это сделать, но получил сообщение об ошибке, в котором говорилось, что только действие может вносить изменения в свои собственные представления (что для меня имеет смысл):

postTransaction:onComplete:DatabaseError: User code called from the Firebase Database runloop threw an exception:
                                                                           android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                               at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7901)
                                                                               at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1360)
                                                                               at android.view.ViewGroup.invalidateChild(ViewGroup.java:5448)
                                                                               at android.view.View.invalidateInternal(View.java:14829)
                                                                               at android.view.View.invalidate(View.java:14793)
                                                                               at android.view.View.setFlags(View.java:12684)
                                                                               at android.view.View.setVisibility(View.java:8673)
                                                                               at website.picl.picl.Activities.TutorChatActivity$7.doTransaction(TutorChatActivity.java:365)
                                                                               at com.google.android.gms.internal.zzdsf.zza(Unknown Source)
                                                                               at com.google.firebase.database.zzf.run(Unknown Source)
                                                                               at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
                                                                               at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                               at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
                                                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)

Итак, возвращаясь к моему вопросу, как бы я иначе использовал результат транзакции для изменения моих представлений (без необходимости использования отдельного слушателя события value, который я бы рассматривал только как последний вариант)из-за того, что он медленнее и приводит к большему количеству обращений к серверу).

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Я нашел способ взаимодействия с представлениями в моей деятельности, не полагаясь на отдельного слушателя:

Я вставляю следующее в оператор IF в своем коде транзакции, как показано в моем исходном вопросе:

getIntent().removeExtra("ORIGIN");
getIntent().putExtra("ORIGIN", "TransactionSuccess");
startActivity(getIntent());

Затем в onCreate моей деятельности я обрабатываю необходимые изменения представления в случае, для которого ORIGIN равен «TransactionSuccess», в операторе IF:

//This is in my onCreate:

Intent intent = getIntent();
String origin = intent.getStringExtra("ORIGIN");

if (origin.equals("TransactionSuccess"){

this.overridePendingTransition(0, 0);

//Set my view changes here.

}

ДополнительноЧтобы избежать скольжения в анимации при обновлении активности, я включаю следующее в тот же оператор onCreate IF (как показано):

this.overridePendingTransition(0, 0);

Этот подход позволяет быстрее изменять представление, чем полагаться на слушателя базы данных..

Все еще существует кратковременная вспышка существующих представлений, поскольку действие возобновляется, но я возьму это на себя в течение сравнительно более длительного времени ожидания слушателя.

0 голосов
/ 23 мая 2018

Клиент базы данных Firebase, запускает все сетевые операции в фоновом потоке.Таким образом, это означает, что вы не можете создавать / изменять представления в этом фоновом потоке.Вы можете изменить пользовательский интерфейс только в потоке, в котором были созданы эти представления.Тем не менее, поток, в котором вам разрешено вносить эти изменения, является основным путем, поэтому вам необходимо извлечь эти строки кода из транзакции.

Решение в вашем случае было бы добавить ValueEventListener (вне транзакции) для данного конкретного значения, и после успешного завершения транзакции будет вызван метод onDataChange(), и внутри этого метода вы можете создавать / изменять столько представлений, сколько вам нужно.

Примечание: Все дерево представлений является однопоточным.Таким образом, вы всегда должны быть в потоке пользовательского интерфейса при вызове любого метода в любом представлении.Если вы работаете с другими потоками и хотите обновить состояние представления из этого потока, вы должны использовать Handler.

Вы можете найти гораздо больше здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...