【问题标题】:Initializing or modifying variable in Parse Query在 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;
}
}

【问题讨论】:

    标签: java android parse-server


    【解决方案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() 方法完成它的工作之后发生。这是完全并发的问题,你必须小心它
    猜你喜欢
    • 2019-08-02
    • 2020-10-03
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    相关资源
    最近更新 更多