android - 从 AsyncTask 返回 ArrayList

标签 android android-asynctask

我正在尝试从服务器获取歌曲的 URL。我想获取数组列表中的所有网址,这些网址可以在下一个 Activity 的回收站 View 中显示。当我尝试使用 Toast 或日志查看它们时,URL 被正确接收。但是当我尝试将它们作为 AsyncTask 的返回结果时,它显示返回的数组列表的大小 = 0。我遵循了 this question 的答案特别是Blackbelt .但事实证明这没有用。该答案的评论被禁用。所以,在这里我用修改后的代码发布我的问题。这是我写的代码。

    interface OnFetchUrlsListener
    {
        public void onUrlsFetched(ArrayList<String> arrayList);
        public void onUrlsError(String error);
    }

     public class SplashScreen extends AppCompatActivity implements OnFetchUrlsListener{

    @Override
    public void onUrlsFetched(ArrayList<String> arrayList) {
        Toast.makeText(this, "result size : "+arrayList.size(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUrlsError(String error) {

    }

    private static RequestQueue mQueue;
    public static ArrayList<String> songsArray ;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);
        songsArray = new ArrayList<String>();
        String uri = Uri.parse("https://dee9c999.ngrok.io/audio/data/WebsiteSourceCode/api/all_songs.php/?allsongs=allsongs").toString();
        new FetchSongs(this).execute(uri);

    }

    private class FetchSongs extends AsyncTask<String, String, ArrayList<String>> {
        private OnFetchUrlsListener mListener;
        public FetchSongs(OnFetchUrlsListener listener){
            mListener = listener;
        }

        @Override
        protected ArrayList<String> doInBackground(String... params) {
            //some heavy processing resulting in a Data String
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, params[0], null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            try {
                                JSONArray jsonArray = response.getJSONArray("data");

                                for (int i = 0; i < jsonArray.length(); i++) {
                                    songsArray.add(jsonArray.getString(i));
                                }

                            }
                            catch (JSONException e) {
                                e.printStackTrace();
                                Log.d("JSON Parse", String.valueOf(e));
                            }

                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                    Toast.makeText(SplashScreen.this, "Load error!!", Toast.LENGTH_SHORT).show();
                }
            });
            mQueue.add(request);
            return songsArray;
        }

        @Override
        protected void onPreExecute() {}

        @Override
        protected void onPostExecute(ArrayList<String> result) {

            if(mListener!=null)
            {
                mListener.onUrlsFetched(result);
            }
        }
    }
}

[编辑]

 private ArrayList<String> startHeavyProcessing(String uri) {
        final ArrayList<String> result = new ArrayList<String>();
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, uri, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            JSONArray jsonArray = response.getJSONArray("data");

                            for (int i = 0; i < jsonArray.length(); i++) {
                                result.add(jsonArray.getString(i));
                                Toast.makeText(SplashScreen.this, jsonArray.getString(i), Toast.LENGTH_SHORT).show();
                            }
                            songs_fetched = true;

                        }
                        catch (JSONException e) {
                            e.printStackTrace();
                            songs_fetched = false;
                            Log.d("JSON Parse", String.valueOf(e));
                        }

                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                Toast.makeText(SplashScreen.this, "Load error!!", Toast.LENGTH_SHORT).show();
            }
        });
        mQueue.add(request);
        return result;
    }

现在,当我尝试打印函数 startHeavyProcessing() 的结果时,它返回一个大小为 0 的数组列表,但在函数内部它正在获取歌曲 url 非常好。

最佳答案

我已经用不同的方式解决了你的问题......

  1. 像往常一样定义这个接口(interface)

    public interface OnFetchUrlsListener {
        void onUrlsFetched(ArrayList<String> arrayList);
        void onUrlsError(String error);
    }
    
  2. 写下一个类,例如 VolleyCall,其中将发生 volley get 请求并使用监听器返回结果/响应

    public class VolleyCall {
        private String TAG = VolleyCall.class.getSimpleName();
        private String mUrl;
        private OnFetchUrlsListener mOnFetchUrlsListener;
        private ArrayList<String> mSongs;
        private RequestQueue mQueue;
    
        public VolleyCall(Context context, String url, OnFetchUrlsListener onFetchUrlsListener) {
            mSongs = new ArrayList<>();
            mUrl = url;
            mOnFetchUrlsListener = onFetchUrlsListener;
    
            mQueue = Volley.newRequestQueue(context);
        }
    
        public void parse() {
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, mUrl, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            Log.e(TAG, "_log : onResponse : response : " + response.toString());
                            JSONArray jsonArray = response.getJSONArray("data");
    
                            for (int i = 0; i < jsonArray.length(); i++) {
                                mSongs.add(jsonArray.getString(i));
                            }
    
                            mOnFetchUrlsListener.onUrlsFetched(mSongs);
    
                        } catch (JSONException e) {
                            Log.e(TAG, "_log : onResponse : JSONException : " + e.getMessage());
                        }
    
                    }
                }, new Response.ErrorListener() {
             @Override
             public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "_log : onErrorResponse : error : " + error.getMessage());
                mOnFetchUrlsListener.onUrlsError(error.getMessage());
            }
        });
    
        mQueue.add(request);
        Log.e(TAG, "_log : songsArray_size : " + mSongs.size());
        }
    }
    
  3. 修改您的主要 Activity

    public class SplashScreen extends AppCompatActivity implements OnFetchUrlsListener {
    
        private String TAG = SplashScreen.class.getSimpleName();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            String url = "https://dee9c999.ngrok.io/audio/data/WebsiteSourceCode/api/all_songs.php/?allsongs=allsongs";
            VolleyCall call = new VolleyCall(SplashScreen.this, url, SplashScreen.this);
            call.parse();
        }
    
        @Override
        public void onUrlsFetched(ArrayList<String> arrayList) {
            Log.e(TAG, "_log : onUrlsFetched : is_arrayList_null : " + (arrayList == null));
            if (arrayList != null) {
                Log.e(TAG, "_log : onUrlsFetched : arrayList_size : " + arrayList.size());
            }
    
            String file_names = "";
            for (String s : arrayList) {
                file_names = file_names.concat(s + "\n");
            }
    
           TextView tv = findViewById(R.id.text);
           tv.setText(file_names);
        }
    
        @Override
        public void onUrlsError(String error) {
            Log.e(TAG, "_log : onUrlsError : " + error);
        }
    }
    

关于android - 从 AsyncTask 返回 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55036060/

相关文章:

android - Samsung Galaxy S adb 驱动程序详细信息?

android - Android 中的应用程序 list 和库 list

java - Android 模拟器错误,控制台错误日志重复错误

java - 如何让异步在后台运行线程?

android - 长延迟AsyncTask并重新启动任务

java - 系统健康 OpenJDK 显示间歇性性能和 UI 问题。我们推荐使用 Oracle JRE/JDK

java - 如何快速检查 URL 服务器是否可用

android - 有没有办法在 AsyncTask 中停止 HttpClient 的执行?

java - 下载照片时遇到问题

android - 保存异步任务结果