我的申请中还有另一个问题。我在MainActivity中使用以下代码从ContactAdapter中获取用户数据:
private List<String> loadContactData() {
ContactAdapter db = new ContactAdapter(getApplicationContext());
// Spinner Drop down elements
List<String> contacts = db.getAllContacts();
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, contacts);
// Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Log.d("SPINNER", String.valueOf(contacts));
return contacts;
}
和ContactAdapter:
public List<String> getAllContacts(){
final List<String> contacts_id = new ArrayList<String>();
final List<String> contacts_name = new ArrayList<String>();
Backendless.Data.of(BackendlessUser.class).find(new AsyncCallback<BackendlessCollection<BackendlessUser>>() {
public void handleResponse(BackendlessCollection<BackendlessUser> users) {
Iterator<BackendlessUser> userIterator = users.getCurrentPage().iterator();
while (userIterator.hasNext()) {
BackendlessUser user = userIterator.next();
String user_mail = user.getEmail();
String user_id = user.getUserId();
contacts_name.add(user_mail);
contacts_id.add(user_id);
}
Log.d("getAllContacts: ", String.valueOf(contacts_name)); }
public void handleFault(BackendlessFault backendlessFault) {
System.out.println("Server reported an error - " + backendlessFault.getMessage());}});
return contacts_name;
}
当然,我的问题是Backendless查询会变慢...因此在我的Logcat中,我首先看到一个空的“ SPINNER”,然后看到带有来自服务器的用户数据的“ getAllContacts”。结果,来自loadContactData()的return contact语句也为空。
如何获得getAllContacts()首先完成才能在loadContactData()中获取用户数据?
最佳答案
您的问题是find
调用是异步的(这很好,这意味着handleResponse()
在新线程上被调用)。因此,当您运行return contacts_name
时,contacts_name
仍为空,因为handleResponse()
中的代码尚未运行,因为新线程仍在等待数据库的响应。
对数据库的调用很慢,因为它可能包含文件或什至是网络IO。您永远不应在使用视图的主线程上执行此操作,否则应用程序将不再响应,因为更新UI(并绘制微调器动画)的主线程正忙于等待数据库。通过使数据库请求异步,您的应用程序将保持响应状态,并且UI不会“卡住”。
为了使事情简单,您可以这样做:
public class MyActivity extends AppCompatActivity {
private List<String> mContactIds = new ArrayList<>();
private Spinner mSpinner;
private ProgressDialog mProgressDialog;
@Overrride
public void onCreate() {
this.setContentView(...);
this.mSpinner = ...;
this.showLoadingDialog();
Backendless.Data.of(BackendlessUser.class).find(new AsyncCallback<BackendlessCollection<BackendlessUser>>() {
public void handleResponse(BackendlessCollection<BackendlessUser> users) {
List<String> mails = new ArrayList<>();
List<String> ids = new ArrayList<>();
Iterator<BackendlessUser> userIterator = users.getCurrentPage().iterator();
while (userIterator.hasNext()) {
BackendlessUser user = userIterator.next();
String mail = user.getEmail();
String id = user.getUserId();
mails.add(user_mail);
ids.add(user_id);
}
Log.d("getAllContacts: ", String.valueOf(contacts_name));
applyData(mails, ids);
}
public void handleFault(BackendlessFault backendlessFault) {
Log.e("error: ", "Something went wrong");
}
});
}
private void applyData(List<String> mails, List<String> ids) {
Log.d("getAllContacts: ", String.valueOf(contacts_name));
this.hideLoadingDialog();
this.mContactIds = ids;
this.mSpinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mails);
}
private void showLoadingDialog() {
this.mLoadingDialog = new ProgressDialog(this, null, "Loading contacts...", true);
this.mLoadingDialog.dismiss();
}
private void hideLoadingDialog() {
if(this.mLoadingDialog != null) {
this.mLoadingDialog().dismiss();
}
}
private void showErrorDialog() {
this.hideLoadingDialog();
new AlertDialog.Builder(this)
.setMessage("Something went wrong, try again")
.setPositiveButton("Ok", null)
.show();
}
}