Android Volley 请求 - 在请求中填充自定义 class 不工作

Android Volley Request - within request populating custom class not working

我有一个 Activity 由一堆 TextView(十四个)和两个按钮组成。 我创建了一个名为 Lesson 的自定义 class,它基本上有一个构造函数和用于其变量的 getter 方法。 现在,在我的 Activity 中的 onCreate() 中,我调用了两个函数:1.) populateLessonDetails(myURL) 和 2.) populateLessonTextViews().

我在我的 Activity 中创建了一个 private Lesson mLesson; 变量,最重要的是 @Overrides,因为我稍后会尝试使用这个变量来填充它。

所以,populateLessonDetails(myURL) 基本上是制作一个 JsonArrayRequest,从 onResponse() 中的 JSON 获取所有数据,将其保存到 String 变量仍然在 onResponse() 内,然后,仍然在 onResponse() 内,我试图通过调用来填充 mLesson 变量 mLesson = new Lesson(mName, mRoom, mExtra, mAddress, mPC, mCity, mStart, mDate, mRID, mMaxAtt, mCurrentAtt); - 构造函数中使用的变量是包含 JSON 数据的 String 变量。

Log.i() JSON 数据以及 mLesson 变量通过它的 getter 方法,数据就在那里。一切都很好。

现在,我的 populateLessonDetails() 结束了。 它 return 到 onCreate() 并继续下一行代码,即调用 populateLessonTextViews()。 这就是事情向南发展的地方...... 一旦函数被调用,我就会尝试通过其 getter 方法获取存储在 mLesson 中的信息,并将其设置为 TextViews ,如下所示:

    //Lesson Name Big
    TextView lessonNameTextBig = (TextView) findViewById(R.id.text_activelesson_name_big);
    lessonNameTextBig.setText(mLesson.getLessonName());

这是正确的做法,我已经做过很多次了,但是我的应用程序在第二行崩溃了。

我已经调试过了,我注意到 mLesson 是空的。我的猜测是,我将它填充到 JsonArrayRequestonResponse() 中,它位于 populateLessonDetails() 中,仅对这个特定函数有效,变量范围 mLesson当函数 returns 到 onCreate()mLesson 变量再次为空时结束,因为它与函数一起死亡。

现在我该如何解决这个问题?我是否必须将 mLesson 设置为 populateLessonDetails() 的参数,然后再将其 return 设置为参数(当前填充函数是 void)?然后将 return 值保存到另一个 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() 方法是一个回调,稍后在网络请求 returned 值时调用。服务器不响应任何延迟。这意味着从 onCreate 调用的 populateLessonDetails(..) 方法会触发网络请求,并且 return 会立即调用此函数的 onCreate() 并继续前进。 你必须考虑到这一点。最好的方法是在 onResponse 内部调用 populateLessonTextViews() 方法。然后就可以确定内容已经加载了。