Java代码仅在我设置断点时才能工作,而在发布模式下不能工作。

huangapple go评论80阅读模式
英文:

Java code working only when I set a breakpoint, not in release mode

问题

我必须在片段中的可回收视图中显示用户列表。 代码没问题,但是当我运行应用程序时列表不会显示出来。

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<Document> 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<Document> db = client.getDatabase("db").getCollection("Users");
        RemoteFindIterable<Document> 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() {...});

但没有效果。请帮忙。谢谢。

英文:

I have to show a list of users in a recycler view in a fragment. The code is fine but the list does not show up when I run the app.

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&lt;User&gt; 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,&quot;mongodb-atlas&quot;);
RemoteMongoCollection db =  client.getDatabase(&quot;db&quot;).getCollection(&quot;Users&quot;);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mUsers = new ArrayList&lt;&gt;();
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, &quot;mongodb-atlas&quot;);
RemoteMongoCollection db = client.getDatabase(&quot;db&quot;).getCollection(&quot;Users&quot;);
RemoteFindIterable docs = db.find();
docs.forEach(new Block&lt;Document&gt;() {
@Override
public void apply(Document document) {
username = document.getString(&quot;username&quot;);
imageURL = document.getString(&quot;imageURL&quot;);
Log.d(&quot;rrrrrrrr&quot;, &quot;apply: &quot; + username + imageURL);
User user = new User(username, imageURL);
mUsers.add(user);
Log.d(&quot;rrrrrrrr&quot;, &quot;apply: &quot; + mUsers);
}
});
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
}
}

Then I tried debugging the code and put a breakpoint on these lines

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

And the list showed up. I didn't know what happened so I removed the breakpoints and the code was not working.
Then I tried adding a breakpoint at

username = document.getString(&quot;username&quot;);

and I run it through each and every line and I found it never goes to those lines mentioned above.
The list was still not showing.
I tried putting

Thread.yield();

Between the lines, but nothing worked.
I even tried to put those lines between

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

But doesn't work.
Please help.
Thank You.

答案1

得分: 0

尝试将方法调用移到 onViewCreated() 中:

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

    } catch (InterruptedException e) {
       e.printStackTrace();
    }
}
英文:

Try to move your method call in onViewCreated()

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

答案2

得分: 0

没有使用过MongoDB,但似乎db.find()返回某种类型的promise集合,而你的apply(Document doc)是异步回调。这意味着你的userAdapter始终使用空数组构造。

但在调试模式下可以工作,因为在适配器构造行上点击“Step”按钮时,异步回调已经起作用并返回了值。

未找到相关文档(甚至是否存在?),因此我将其添加到项目中,并发现你可以将**OnCompleteListener**添加到RemoteFindIterable。那应该是创建适配器的地方。

此外,考虑在onCreateView中将适配器附加到RecyclerView,但在onSuccessListener中调用notifyDataSetChanged()

英文:

Haven't worked with MongoDB, but it seems like db.find() returns a collection of some sort of promises, and your apply(Document doc) are asynchronous callbacks. That means that your userAdapter is always constructed with empty array.

But it works in debug mode because asynchronous callbacks have worked and returned values by the time you click on the "Step" button on the adapter construction line.

Could not find the documentation for it (does it even exist?), so I added it to project and found that you can add OnCompleteListener to the RemoteFindIterable. That should be the place to make an adapter.

        docs.forEach(new Block&lt;Document&gt;() {
@Override
public void apply(Document document) {
username = document.getString(&quot;username&quot;);
imageURL = document.getString(&quot;imageURL&quot;);
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);
}
});

Also, consider attaching an adapter to RecyclerView in onCreateView, but in onSuccessListener calling notifyDataSetChanged()on it.

huangapple
  • 本文由 发表于 2020年4月5日 01:25:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/61031977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定