在 Parse Query 中初始化或修改变量
Posted
技术标签:
【中文标题】在 Parse Query 中初始化或修改变量【英文标题】:Initializing or modifying variable in Parse Query 【发布时间】:2018-08-12 17:06:03 【问题描述】:我创建了一个名为“Roommate”的类,它是使用 ParseUser 变量构造的,我尝试创建一个新的 Roommate 对象并将其添加到我的 Roommate arrayList。但是,查询完成后,似乎我所做的任何修改或初始化都会被重置。查询完成后,我的 arrayList 最终为空。有谁知道这是为什么以及我可以做些什么来解决这个问题?
如果这是一个基本问题,我深表歉意。我是一名学生,这是我第一次尝试制作应用程序。感谢所有反馈。
我调用 updateRoommatesArray() 的 ArrayList 和 OnCreate 方法:
// variables
private ArrayList<Roommate> roommates = new ArrayList<>();
AddRoommateRecyclerViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_roommates);
// Set up toolbar
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar_roommate);
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Add Roommates");
// Set up floating action button
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
//show dialog on click
AddRoommatesDialog addRoommatesDialog = new AddRoommatesDialog();
addRoommatesDialog.show(getSupportFragmentManager(),"add roommates dialog");
);
// Initializes roommateNames with data from Parse
updateRoommatesArray();
Toast.makeText(this, Integer.toString(roommates.size()), Toast.LENGTH_SHORT).show();
// Set up Recycler View
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
RecyclerView recyclerView = findViewById(R.id.rm_recycler);
recyclerView.setLayoutManager(layoutManager);
adapter = new AddRoommateRecyclerViewAdapter(this, roommates);
recyclerView.setAdapter(adapter);
updateRoommatesArray 方法:
public void updateRoommatesArray()
roommates.clear();
final ParseUser currentUser = ParseUser.getCurrentUser();
ParseRelation<ParseUser> relation = currentUser.getRelation("roommates");
relation.getQuery().findInBackground(new FindCallback<ParseUser>()
@Override
public void done(List<ParseUser> objects, ParseException e)
if (e == null && objects.size() > 0)
for (ParseUser roommate : objects)
Roommate current_roommate = new Roommate(roommate);
roommates.add(current_roommate);
else
Log.i("Query", "Empty or Not Working");
);
室友班:
public class Roommate
// Member Variables
String objectId;
String username;
String firstName;
String lastName;
String fullName;
ArrayList<Roommate> roommates;
// Constructor
public Roommate(ParseUser user_in)
objectId = user_in.getObjectId().toString();
username = user_in.getUsername().toString();
firstName = user_in.get("firstName").toString();
lastName = user_in.get("lastName").toString();
fullName = firstName + " " + lastName;
roommates = new ArrayList<>();
public String getObjectId()
return objectId;
public String getUsername()
return username;
public String getFirstName()
return firstName;
public String getLastName()
return lastName;
public String getFullName()
return fullName;
public ArrayList<Roommate> getRoommates()
return roommates;
【问题讨论】:
【参考方案1】:问题刚刚出现,因为findInBackground()方法是异步方法调用。无法保证设置 RecyclerAdaptor 的适配器会在终止 findInBackground 的作业后执行。
请注意,您在 updateRoommatesArray 的第一行中清楚地列出了列表。然后你开始一个异步任务。之后主线程想要继续它的工作并返回到 onCreate() 方法来设置 ArrayList。它将无限期地发生。
从本质上讲,从数据库加载数据将比在主线程中执行简单的代码花费更长的时间。
所以很可能 recyclerView.setAdapter(adapter);将在数组被填充到 done() 方法之前执行。
为了确保适配器将被填充,请将以下代码放入 done 方法中。这样做,您将保证正确的代码执行顺序。
Toast.makeText(this, Integer.toString(roommates.size()), Toast.LENGTH_SHORT).show();
// Set up Recycler View
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
RecyclerView recyclerView = findViewById(R.id.rm_recycler);
recyclerView.setLayoutManager(layoutManager);
adapter = new AddRoommateRecyclerViewAdapter(this, roommates);
recyclerView.setAdapter(adapter);
【讨论】:
谢谢你说得通。如果我不能确定 findInBackground() 方法何时完成,有什么方法可以在另一个函数中访问存储在室友 arrayList 中的值? 如果您熟悉 EDA,您可以引发一个事件并在主线程下运行的所需订阅者中捕获它,请参阅 GreenRobot EventBus。在任何情况下,您都必须确保填充 RecyclerAdapter 的调用方法必须在 done() 方法完成它的工作之后发生。这是完全并发的问题,你必须小心它以上是关于在 Parse Query 中初始化或修改变量的主要内容,如果未能解决你的问题,请参考以下文章
在 Parse 服务器 CloudCode 中使用已初始化的邮件适配器