我使用Realm开发我的登录应用程序。 我在Realm中写了我的令牌' Config myConfig = mRealm.createObject(Config.class)'。之后从Realm读取没有结果同样Realm没有条目。 我会检查这段代码,我标记为' //检查 - 为什么没有这里的用户'。 而User.size()等于零。
public class MainActivity extends AppCompatActivity {
private Realm mRealm;
private Realm mRealmInstance;
Button btnLogin;
public void onLogin() {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams rp = new RequestParams();
rp.add("email", "name@example.com");
rp.add("password", "159753");
RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// Root JSON in response is an dictionary i.e { "data : [ ... ] }
// Handle resulting parsed JSON response here
try {
String tokenString = response.getString("token");
mRealm.beginTransaction();
Config myConfig = mRealm.createObject(Config.class);
myConfig.name = "token";
myConfig.tokenValue = tokenString;
mRealm.commitTransaction();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
});
//check - why no users here
TextView tvHello = (TextView)findViewById(R.id.tvHello);
try {
RealmResults User = mRealmInstance.where(Config.class).equalTo("name", "token").findAllAsync();
if (User.size() > 0) {
String nameOfUser = User.get(0).toString();
tvHello.setText(nameOfUser);
} else if (User.size() == 0) {
Log.e("query","query size is "+User.size());
}
} catch (Exception e) {
e.printStackTrace();
}
//end of test block
}
答案 0 :(得分:2)
您在访问数据之前正在进行异步网络呼叫。网络呼叫尚未完成,因此您的数据为空。将您的数据访问代码放在onSuccess()
回调中。
public class MainActivity extends AppCompatActivity {
...
public void onLogin() {
...
RequestHandle post = client.post(
"https://example.com/api/v1/auth",
rp,
new JsonHttpResponseHandler() {
@Override
public void onSuccess(
int statusCode,
Header[] headers,
JSONObject response) {
try {
String tokenString = response.getString("token");
mRealm.beginTransaction();
Config myConfig = mRealm.createObject(Config.class);
myConfig.name = "token";
myConfig.tokenValue = tokenString;
mRealm.commitTransaction();
populateData();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(
int statusCode,
Header[] headers,
String res,
Throwable t) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
});
}
private void populateData() {
TextView tvHello = (TextView)findViewById(R.id.tvHello);
try {
RealmResults User =
mRealmInstance.where(Config.class).equalTo("name", "token").findAll();
if (User.size() > 0) {
String nameOfUser = User.get(0).toString();
tvHello.setText(nameOfUser);
} else if (User.size() == 0) {
Log.e("query","query size is "+User.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
另请注意,您应使用findAll()
代替findAllAsync()
。阅读文档以获取有关差异的更多信息:https://realm.io/blog/realm-java-0-84-0/
答案 1 :(得分:1)
这是因为client.post(...
将在另一个线程中执行。只有在该任务完成后,才会在UI线程中执行onSuccess()
。 //check - why no users here
之后的代码在执行onSuccess()
之前或之后执行。这就是User.size()
等于零的原因。修改代码以使其正常工作
public class MainActivity extends AppCompatActivity {
private Realm mRealm;
private Realm mRealmInstance;
private TextView tvHello;
Button btnLogin;
public void onLogin() {
tvHello = (TextView) findViewById(R.id.tvHello);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams rp = new RequestParams();
rp.add("email", "name@example.com");
rp.add("password", "159753");
RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// Root JSON in response is an dictionary i.e { "data : [ ... ] }
// Handle resulting parsed JSON response here
try {
String tokenString = response.getString("token");
mRealm.beginTransaction();
Config myConfig = mRealm.createObject(Config.class);
myConfig.name = "token";
myConfig.tokenValue = tokenString;
mRealm.commitTransaction();
RealmResults User = mRealmInstance.where(Config.class).equalTo("name", "token").findAllAsync();
if (User.size() > 0) {
String nameOfUser = User.get(0).toString();
tvHello.setText(nameOfUser);
} else if (User.size() == 0) {
Log.e("query", "query size is " + User.size());
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
});
}
}
答案 2 :(得分:1)
要在从后台线程写入Realm时接收通知,您应该使用RealmChangeListener(并将RealmResults保留为字段)。
public class MainActivity extends AppCompatActivity {
private Realm realm;
Button btnLogin;
private RealmResults<Config> userResults;
private RealmChangeListener<RealmResults<Config>> changeListener = new RealmChangeListener<RealmResults<Config>>() {
@Override
public void onChange(RealmResults<Config> element) {
TextView tvHello = (TextView)findViewById(R.id.tvHello);
try {
if (element.size() > 0) {
String nameOfUser = element.get(0).toString();
tvHello.setText(nameOfUser);
} else if (element.size() == 0) {
Log.e("query","query size is "+element.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(..);
realm = Realm.getDefaultInstance();
userResults = realm.where(Config.class).equalTo("name", "token").findAllAsync();
userResults.addChangeListener(changeListener);
}
@Override
public void onDestroy() {
super.onDestroy();
userResults.removeAllChangeListeners();
userResults = null;
realm.close();
realm = null;
}
public void onLogin() {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams rp = new RequestParams();
rp.add("email", "name@example.com");
rp.add("password", "159753");
RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// Root JSON in response is an dictionary i.e { "data : [ ... ] }
// Handle resulting parsed JSON response here
try {
String tokenString = response.getString("token");
try(Realm r = Realm.getDefaultInstance()) {
r.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Config myConfig = realm.createObject(Config.class);
myConfig.name = "token";
myConfig.tokenValue = tokenString;
}
});
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
});
//end of test block
}