方法内非final变量初始化及JsonRequest中sleep使用问题咨询
Hey there, let's tackle your two issues step by step—they're common pitfalls when working with Android's async requests, so you're not alone!
方法内变量初始化
First off, you're already on the right track with initializing variables inside your method! Your line:
DataModel[] dataModels = new DataModel[count];
is exactly how you initialize a variable within a method. If you're trying to assign values to these variables inside the JsonRequest callback, that ties into your second issue, which we'll cover next.
关于在JsonRequest中使用sleep
Big warning here: Never call Thread.sleep() inside the Response.Listener callback (or any main thread code)! The callback runs on Android's main thread, and blocking it with sleep will trigger an ANR (Application Not Responding) error—your app will freeze and might crash.
If you need to delay an action after the request completes, use a Handler with postDelayed() instead. Here's how:
// Inside your Response.Listener callback Handler mainHandler = new Handler(Looper.getMainLooper()); mainHandler.postDelayed(new Runnable() { @Override public void run() { // Code you want to run after a delay goes here // Example: Update UI or process data } }, 2000); // Delay in milliseconds (2 seconds here)
This error happens because anonymous inner classes (like your Response.Listener) can only access variables from the outer scope that are final or "effectively final" (Java 8+). "Effectively final" means the variable's value doesn't change after initialization—even if you don't explicitly mark it as final.
你的场景的解决方案
Looking at your code, you're initializing dataModels as an array and then populating its elements in the callback. Since arrays are reference types, you don't need to reassign the entire array—you just modify its contents. So you can safely mark dataModels as final:
public DataModel[] getContentsUsername(final int count) { final DataModel[] dataModels = new DataModel[count]; for (int i = 0; i < count; i++) { dataModels[i] = new DataModel(); } JsonArrayRequest jsonArrayRequest = new JsonArrayRequest( "http://www.lmslfm.isteb.ir/message/json.php", new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { // Now you can modify elements inside dataModels without issues try { for (int i = 0; i < response.length(); i++) { JSONObject obj = response.getJSONObject(i); dataModels[i].setUsername(obj.getString("username")); // Set other DataModel fields here } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); } } ); // Add the request to your Volley RequestQueue RequestQueue queue = Volley.newRequestQueue(context); queue.add(jsonArrayRequest); return dataModels; }
如果确实需要重新赋值变量
If you ever need to reassign the entire variable (not just modify its contents), use a wrapper class like AtomicReference to hold the variable. This lets you update the value inside the callback without making the variable final:
public DataModel[] getContentsUsername(final int count) { AtomicReference<DataModel[]> dataModelsRef = new AtomicReference<>(new DataModel[count]); // ... rest of your code ... new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { // Reassign the entire array DataModel[] newModels = new DataModel[response.length()]; // Populate newModels... dataModelsRef.set(newModels); } }; return dataModelsRef.get(); }
内容的提问来源于stack exchange,提问作者Ebrahim Bashirpour

