我有一个由一堆 TextView(十四个)和两个 Button 组成的 Activity。
我创建了一个名为 Lesson
的自定义类,它基本上有一个构造函数和其变量的 getter 方法。
现在,在 Activity 的 onCreate()
中,我正在调用两个函数:1.) populateLessonDetails(myURL)
和 2.) populateLessonTextViews()
.
我在我的 Activity 中创建了一个 private Lesson mLesson;
变量,位于所有 @Overrides
之上,因为我稍后尝试使用此变量来填充它.
因此,populateLessonDetails(myURL)
基本上是在创建一个 JsonArrayRequest
,从 onResponse()
内的 JSON 获取所有数据,保存它仍然位于 onResponse()
内的 String
变量,然后,仍在 onResponse()
内,我试图填充 mLesson
变量,通过调用
mLesson = new Lesson(mName, mRoom, mExtra, mAddress, mPC, mCity, mStart, mDate, mRID, mMaxAtt, mCurrentAtt);
- 构造函数中使用的变量是 String
包含 JSON 数据的变量。
我通过其 getter 方法获取了 Log.i()
JSON 数据以及 mLesson
变量,并且数据就在那里。一切都很好。
现在,我的 populateLessonDetails()
结束了。
它返回到 onCreate()
并继续执行下一行代码,其中将调用 populateLessonTextViews()
。
事情就这样向南发展了……
一旦调用该函数,我就会尝试通过其 getter 方法获取存储在 mLesson
中的信息,并将其设置为 TextViews
,如下所示:
//Lesson Name Big
TextView lessonNameTextBig = (TextView) findViewById(R.id.text_activelesson_name_big);
lessonNameTextBig.setText(mLesson.getLessonName());
这是正确的方法,我已经这样做了很多次,但我的应用程序在第二行崩溃了。
我已经调试了它,我注意到 mLesson
是空的。我的猜测是,我将其填充到 JsonArrayRequest
的 onResponse()
中(位于 populateLessonDetails()
内部)仅对此有效特定函数,当函数返回到 onCreate()
时,变量 mLesson
的作用域结束,且 mLesson
变量自死亡后再次为空与功能。
现在我该如何解决这个问题?我是否必须将 mLesson
设置为 populateLessonDetails()
的参数,然后返回它(当前填充函数为 void
)?然后将返回值保存到另一个Lesson类型的变量中,并将这个新变量设置为populateLessonTextViews()
的参数?我已经尝试过一些这样的事情,但它们不起作用,但也许只是我做得不对。
这就是我的代码的样子(重要部分):
public class ActiveLesson extends AppCompatActivity {
// there are also some other variables up here
private Lesson mLesson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_active_lesson);
requestQ = Volley.newRequestQueue(this);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
mDatum = extras.getString("datum");
mRID = extras.getString("rid");
mVon = extras.getString("von");
myActiveLessonURLFiltered += "datum="+mDatum+"&rid="+mRID+"&von="+mVon;
populateLessonDetails(myActiveLessonURLFiltered);
populateLessonTextViews();
}
private void populateLessonDetails(String myActiveLessonURLFiltered) {
JsonArrayRequest lessonJAR = new JsonArrayRequest(myActiveLessonURLFiltered,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response){
try{
for (int i=0; i < response.length(); i++)
{
JSONObject jsonObject = response.getJSONObject(i);
String mName = jsonObject.getString("Name");
String mRoom = jsonObject.getString("Raum");
String mExtra = jsonObject.getString("Zusatz");
String mAdresse = jsonObject.getString("Address");
String mPC = jsonObject.getString("PLZ");
String mCity = jsonObject.getString("City");
String mMaxAtt = jsonObject.getString("maxAnz");
String mCurrentAtt = jsonObject.getString("belegtAnz");
if(mExtra.length()==0 || mExtra == "null")
mExtra="";
if(mRoom.length()==0 || mRoom == "null")
mRoom="";
else
mRoom="Room: "+mRoom;
if(mName.length()==0 || mName == "null")
mName="";
mLesson = new Lesson(mName, mRoom, mExtra, mAdresse,
mPC, mCity, mVon, mDatum, mRID, mMaxAtt, mCurrentAtt);
Log.i("mmLesson"," Lesson with new = "+ mLesson.getLessonName()
+" "+mLesson.getLessonCity());
}
}catch (JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error){
error.printStackTrace();
Toast.makeText(ActiveLesson.this, "No Lessons Available",
Toast.LENGTH_LONG).show();
}
}){
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
}
};
requestQ.add(lessonJAR);
}
private void populateLessonTextViews(Lesson mLesson) {
//Lesson Name Big
TextView lessonNameTextBig = (TextView) findViewById(R.id.text_activelesson_name_big);
lessonNameTextBig.setText(mLesson.getLessonName());
// there are others lines of code like these two,
// but I've left them out, since they are all the same
}
如果有人可以帮助我,我将不胜感激。谢谢!
最佳答案
onResponse()
方法是一个回调,稍后当网络请求返回值时调用。服务器不会有任何延迟响应。这意味着从 onCreate 调用的 populateLessonDetails(..)
方法会触发网络请求,并立即返回到该函数的 onCreate()
调用并继续前进。
你必须考虑到这一点。最好的方法是在 onResponse 内部调用 populateLessonTextViews()
方法。然后就可以确定内容已经加载了。
关于java - Android Volley 请求 - 在请求中填充自定义类不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34701137/