0

I know it sounds strange/ridiculous, but I am having this issue

Update#2

I am sharing the code that is indicated by @EpicPandaForce.

SyncService.onNetworkSuccess

public void onNetworkCallSuccess(Response response) {
    List<TransactionHistory> historyList = (List<TransactionHistory>) response.body();
    if(historyList != null && historyList.size() > 0) {
        TransactionHistory max = Collections.max(historyList, new Comparator<TransactionHistory>() {
            @Override
            public int compare(TransactionHistory o1, TransactionHistory o2) {
                return o1.getUpdatedAt().compareTo(o2.getUpdatedAt());
            }
        });

        if(max != null) {
            session.putStringForKey(Session.timeStamp, String.valueOf(max.getUpdatedAt()));
        }
        for(TransactionHistory history : historyList) {
            String id;
            if(history.getTo().equals(history.getFrom()) ||
                    history.getFrom().equals(session.getStringForKey(Session.fpIdKey)))
                id = history.getTo();
            else id = history.getFrom();


            LatestTransactionResponse latestTransactionResponse = new LatestTransactionResponse();
            DateTransactionResponse dateTransactionResponse = new DateTransactionResponse(DateUtility.getDateFromEpoch(history.getEpoch()));

            dateTransactionResponse.addTransaction(history);
            latestTransactionResponse.setArchived(history.isArchived());
            latestTransactionResponse.addTransaction(history);
            latestTransactionResponse.setId(id);
            dateTransactionResponse.setId(id);
            LatestTransactionRepository.getInstance().addLatestTransaction(realm,
                    latestTransactionResponse);
            ContactTransactionRepository.getInstance().addNewTransaction(realm, dateTransactionResponse, id);
        }

        try {
            Activity temp = MyFirebaseMessagingService.getRunningActivity();
            if(temp != null) {
                if(temp instanceof MainActivity) {
                    ((MainActivity) temp).refreshLatestTransactions();

                } else if(temp instanceof TransactionDetailActivity) {
                    ((TransactionDetailActivity) temp).refreshOnMainThread();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

addNewTransaction

public void addNewTransaction(Realm realm, final DateTransactionResponse response, final String id) {
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            List<TransactionHistory> tempHistoryList;
            DateTransactionResponse temp = realm
                    .where(DateTransactionResponse.class)
                    .equalTo("id", id)
                    .equalTo("date", response.getDate())
                    .findFirst();

            if(temp == null)
                realm.insertOrUpdate(response);
            else {
                tempHistoryList = temp.getTransactions();

                for(TransactionHistory history : response.getTransactions()) {
                    boolean found = false;
                    for(int i=0; i < tempHistoryList.size(); i++) {
                        if (history.getId().equals(tempHistoryList.get(i).getId())) {
                            if(history.getStatus().equals(tempHistoryList.get(i).getStatus())) {
                                found = true;
                                break;
                            } else {
                                tempHistoryList.get(i).setStatus(history.getStatus());
                            }
                        }
                    }
                    if(!found)
                        tempHistoryList.add(history);
                }

                //realm.insertOrUpdate(temp);
                realm.copyToRealm(temp);

                //DateTransactionResponse transactionResponse = temp;
                //temp.deleteFromRealm();
                //realm.insertOrUpdate(temp);
            }
        }
    });
    //removeDuplicateTransactions(realm);
}

removeDuplicateTransaction

private void removeDuplicateTransactions(Realm realm) {
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            RealmQuery<DateTransactionResponse> query = realm.where(DateTransactionResponse.class);
            RealmResults<DateTransactionResponse> results = query.findAll();
            List<DateTransactionResponse> transactions = new ArrayList<>(results);
            for(DateTransactionResponse response : transactions) {
                List<TransactionHistory> historyList = response.getTransactions();
                Set<TransactionHistory> historySet = new LinkedHashSet<>(historyList);

                RealmList<TransactionHistory> histories = new RealmList<>();
                histories.addAll(new ArrayList<>(historySet));

                response.setTransactions(histories);

                realm.copyToRealm(response);
            }

        }
    });

}

Update#1

There are 3 tabs with RecyclerViews on my main screen. Below are the implementation of Adapter for all three.

I have been developing an App for quite a time. It has been working just fine and I occasionally work to improve its performance. It is still under development. Some days ago, I cut-out the branch and done nothing notable (just one or two bug fixes) and started testing it and OOPS it started giving ANR's. I revert back to previous branch and very strangely it started giving me the same result. I have removed all changes and tried, still the same result. I am not sure what's happening. I tried to study traces.txt, but couldn't find waiting to lock as suggested in this SO answer.

I have also difficulty reading traces, couldn't find the culprit. Here is the traces.txt file.

I am using Realm as Database in my application and couldn't find a way to perform operations on Realm on other thread. I tried to find any other culprit in code, but all is till the same as before which was working perfectly fine.

Hierarchy

Here is the App Hierarchy.

Login screen is shown and user enters PIN. Then comes the main screen. Main screen contains 4 tabs, just like WhatsApp i.e first tab is camera and rest contains RecyclerViews in which data is being populated from Realm. ANR is only happening here. Keeping in mind that it was literally perfect some days ago until I took branch out and fixed some bugs, which were not even related to the main screen.

Any help or direction is highly appreciated.

Waqas Ahmed Ansari
  • 1,683
  • 15
  • 30
  • any heavy operation you are performing on main thread? – Abdul Waheed Jan 12 '18 at 10:22
  • or you fetching heavy amount of data from database? – Abdul Waheed Jan 12 '18 at 10:23
  • Yes, from `Realm` database. It's not that much heavy, but more importantly it was very smooth. It starts happening now. – Waqas Ahmed Ansari Jan 12 '18 at 10:28
  • Well I also had trouble reading the traces file: `{"success":false,"error":404,"message":"Not Found"}` :P – EpicPandaForce Jan 12 '18 at 11:36
  • Do you by chance use `copyFromRealm()`? – EpicPandaForce Jan 12 '18 at 11:37
  • If you can post the data fill code and the adapter code and the query and all that then that would be great – EpicPandaForce Jan 12 '18 at 11:51
  • @EpicPandaForce I have edited the link, you can see it [here](https://ufile.io/ppse1). NO, I didn't use `copyFromRealm` anywhere. I will update my question with adapter code. Thanks – Waqas Ahmed Ansari Jan 12 '18 at 12:47
  • It says you are doing write transaction on UI thread, and also you are most likely doing it per item instead of in a single transaction. You generally shouldn't run write transaction on UI thread – EpicPandaForce Jan 12 '18 at 12:57
  • at io.realm.BaseRealm.commitTransaction(BaseRealm.java:320) at io.realm.Realm.commitTransaction(Realm.java:126) at io.realm.Realm.executeTransaction(Realm.java:1326) at com.pakrupay.app.realm.repository.ContactTransactionRepository.removeDuplicateTransactions(ContactTransactionRepository.java:310) at com.pakrupay.app.realm.repository.ContactTransactionRepository.addNewTransaction(ContactTransactionRepository.java:405) at com.pakrupay.app.service.SyncService$1$1.onNetworkCallSuccess(SyncService.java:109) – EpicPandaForce Jan 12 '18 at 12:57
  • So you should add code for SyncService.onNetworkSuccess, addNewTransaction, and especially removeDuplicateTransactions – EpicPandaForce Jan 12 '18 at 13:05
  • Glad to see you've added code, but you should have added `ContactTransactionReposito‌ry.removeDuplicateTr‌​ansactions` (and `addNewTransaction‌`). :p – EpicPandaForce Jan 12 '18 at 15:33
  • There is no way that `performFiltering()` method works correctly!!! – EpicPandaForce Jan 12 '18 at 15:35
  • Thank you so much for your direction. I would love to hear suggestions about `performFiltering`, it is working so far. Moreover, all the methods you are indicating are already run, they are not causing the issue (i think, I might be wrong). I am sharing code though. – Waqas Ahmed Ansari Jan 13 '18 at 06:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163089/discussion-between-waqas-ahmed-ansari-and-epicpandaforce). – Waqas Ahmed Ansari Jan 13 '18 at 06:09
  • Welp, that's a bit more complicated than for me to just start changing parts of it. The write transaction should be off the UI thread. You could even try using executeTransactionAsync and its onSuccess callback – EpicPandaForce Jan 13 '18 at 10:32
  • Thanks @EpicPandaForce, it improved execution a lot. But again the problem is as it was. All of these realm executions are already run when this happens. – Waqas Ahmed Ansari Jan 15 '18 at 04:40

0 Answers0