Java код работает только когда я устанавливаю точку останова, а не в режиме выпуска - PullRequest
0 голосов
/ 04 апреля 2020

Я должен показать список пользователей в представлении переработчика во фрагменте. Код в порядке, но список не отображается, когда я запускаю приложение.

package com.example.demo;

import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.demo.Model.User;
import com.mongodb.Block;
import com.mongodb.DBObject;
import com.mongodb.stitch.android.core.Stitch;
import com.mongodb.stitch.android.core.StitchAppClient;
import com.mongodb.stitch.android.services.mongodb.remote.RemoteFindIterable;
import com.mongodb.stitch.android.services.mongodb.remote.RemoteMongoClient;
import com.mongodb.stitch.android.services.mongodb.remote.RemoteMongoCollection;
import com.mongodb.stitch.android.services.mongodb.remote.RemoteMongoCursor;

import org.bson.Document;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class UsersFragment extends Fragment {

private RecyclerView recyclerView;
private  UserAdapter userAdapter = null;
private List<User> mUsers = null;
private String username;
private String imageURL;


@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fargment_users,container,false);
    recyclerView = view.findViewById(R.id.recycler_view);
    StitchAppClient stitchAppClient = Stitch.getDefaultAppClient();
    RemoteMongoClient client = stitchAppClient.getServiceClient(RemoteMongoClient.factory,"mongodb-atlas");
    RemoteMongoCollection db =  client.getDatabase("db").getCollection("Users");
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    mUsers = new ArrayList<>();
    mUsers.clear();

    try {
        readUsers();

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


    return view;
}

private void readUsers() throws InterruptedException {
    StitchAppClient stitchAppClient = Stitch.getDefaultAppClient();
    RemoteMongoClient client = stitchAppClient.getServiceClient(RemoteMongoClient.factory, "mongodb-atlas");
    RemoteMongoCollection db = client.getDatabase("db").getCollection("Users");
    RemoteFindIterable docs = db.find();
    docs.forEach(new Block<Document>() {
        @Override
        public void apply(Document document) {
            username = document.getString("username");
            imageURL = document.getString("imageURL");

            Log.d("rrrrrrrr", "apply: " + username + imageURL);
            User user = new User(username, imageURL);
            mUsers.add(user);
            Log.d("rrrrrrrr", "apply: " + mUsers);

        }

    });

    userAdapter = new UserAdapter(getContext(), mUsers);
    recyclerView.setAdapter(userAdapter);
}
}

Затем я попытался отладить код и поставить точки останова на эти строки

userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);

И список появился. Я не знал, что случилось, поэтому я убрал точки останова, и код не работал. Затем я попытался добавить точку останова на

username = document.getString("username");

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

Thread.yield();

между строк, но ничего не получалось. Я даже пытался поместить эти строки между

getActivity.runOnUiThread(){new Runnable{...}}

, но не работает. Пожалуйста помоги. Спасибо.

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Не работал с MongoDB, но похоже, что db.find() возвращает набор неких обещаний, а ваши apply(Document doc) являются асинхронными обратными вызовами. Это означает, что ваш userAdapter всегда создается с пустым массивом.

Но он работает в режиме отладки, потому что асинхронные обратные вызовы работали и возвращали значения к тому времени, когда вы нажимаете кнопку «Шаг» в строке построения адаптера.

Не удалось найти документацию для него (он вообще существует?), поэтому я добавил его в проект и обнаружил, что вы можете добавить OnCompleteListener к RemoteFindIterable. Это должно быть место для создания адаптера.

        docs.forEach(new Block<Document>() {
            @Override
            public void apply(Document document) {
                username = document.getString("username");
                imageURL = document.getString("imageURL");
                User user = new User(username, imageURL);
                mUsers.add(user);
            }
        }).addOnSuccessListener(new OnSuccessListener() {
            @Override
            public void onSuccess(Object o) {
                userAdapter = new UserAdapter(getContext(), mUsers);
                recyclerView.setAdapter(userAdapter);
            }
        });

Также рассмотрите возможность подключения адаптера к RecyclerView в onCreateView, но в onSuccessListener вызову notifyDataSetChanged() для него.

0 голосов
/ 04 апреля 2020

Попробуйте переместить вызов метода в onViewCreated()

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        try {
           readUsers();

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


    }
...