第二个函数在第一个函数完全执行之前执行
Second fuction executes before the first fuction is completely executed
我有两个函数 fetchData() 和 setDataUI(),在 fetchData() 中我发送请求并保存响应。在 setDataUI() 函数中,我正在设置适配器以绑定数据。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
recyclerView = (RecyclerView) findViewById(R.id.image_recycler_view);
data_list = new ArrayList<>();
fetchData2(1);
}
fetchData2() 从服务器获取数据。
public void fetchData2(final int next){
String url = Constants.URL+"image/gallery?page="+next;
Log.d(TAG,"Data2 Url-->"+url);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ActivityImageGallery.this, "Server Error!!!!", Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
然后在 setDataUI()
private void setDataToUI() {
gridLayoutManager = new GridLayoutManager(this,1);
recyclerView.setLayoutManager(gridLayoutManager);
Log.d(TAG,"Data_List-->"+data_list);
adapter = new AdapterImageGallery(this, data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size()-1){
fetchData2(data_list.get(data_list.size()-1).getNext());
}
}
});
}
预期结果:
函数 setDataUI() 必须仅在 fetchData2() 完全执行完毕时启动。因此,setDataUI() 中的 data_list 将具有在 fetchData2() 中初始化的值。
实际结果:
当前 setDataUI() 在 fetchData2() 完成执行之前开始执行,导致 data_list 在 setDataUI() 中为空。
我确实从服务器得到了正确的响应,但是在执行 setDataUI() 之后。
Volleys 的请求是异步的。所以,你应该从回调中调用你的 setDataToUI
:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// all your code
runOnUiThread(new Runnable() {
@Override
public void run() {
setDataToUI();
}
}
}
你需要做的只是在你的响应方式中像下面这样改变,
@Override
public void onResponse(String response) {
try {
if(response.isSuccessful){
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
}
setDataToUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
-把setDataToUI(); onresponse 中的 for 循环完成后的方法调用。
-此外,您的第二个方法在您的第一个方法之前执行,因为您的第一个方法是异步的(即,在另一个线程上工作。它不在主线程或 UI 线程中执行)。
这是因为在您的 fetchData()
中,异步任务 运行 在后台运行,您无法预测它需要多少时间。因此,与其在 fetchData2()
函数之后调用 setDataToUI()
,不如在 fetchData2()
函数的响应中调用它。您可以在 fetchData2 Function
中编辑它
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataToUI()
我有两个函数 fetchData() 和 setDataUI(),在 fetchData() 中我发送请求并保存响应。在 setDataUI() 函数中,我正在设置适配器以绑定数据。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
recyclerView = (RecyclerView) findViewById(R.id.image_recycler_view);
data_list = new ArrayList<>();
fetchData2(1);
}
fetchData2() 从服务器获取数据。
public void fetchData2(final int next){
String url = Constants.URL+"image/gallery?page="+next;
Log.d(TAG,"Data2 Url-->"+url);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ActivityImageGallery.this, "Server Error!!!!", Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
然后在 setDataUI()
private void setDataToUI() {
gridLayoutManager = new GridLayoutManager(this,1);
recyclerView.setLayoutManager(gridLayoutManager);
Log.d(TAG,"Data_List-->"+data_list);
adapter = new AdapterImageGallery(this, data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size()-1){
fetchData2(data_list.get(data_list.size()-1).getNext());
}
}
});
}
预期结果: 函数 setDataUI() 必须仅在 fetchData2() 完全执行完毕时启动。因此,setDataUI() 中的 data_list 将具有在 fetchData2() 中初始化的值。
实际结果: 当前 setDataUI() 在 fetchData2() 完成执行之前开始执行,导致 data_list 在 setDataUI() 中为空。
我确实从服务器得到了正确的响应,但是在执行 setDataUI() 之后。
Volleys 的请求是异步的。所以,你应该从回调中调用你的 setDataToUI
:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// all your code
runOnUiThread(new Runnable() {
@Override
public void run() {
setDataToUI();
}
}
}
你需要做的只是在你的响应方式中像下面这样改变,
@Override
public void onResponse(String response) {
try {
if(response.isSuccessful){
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
}
setDataToUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
-把setDataToUI(); onresponse 中的 for 循环完成后的方法调用。 -此外,您的第二个方法在您的第一个方法之前执行,因为您的第一个方法是异步的(即,在另一个线程上工作。它不在主线程或 UI 线程中执行)。
这是因为在您的 fetchData()
中,异步任务 运行 在后台运行,您无法预测它需要多少时间。因此,与其在 fetchData2()
函数之后调用 setDataToUI()
,不如在 fetchData2()
函数的响应中调用它。您可以在 fetchData2 Function
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataToUI()