Android 带有 AsyncTask 替代项的简单列表

Android simple list with AsyncTask alternative

我有一个 AsyncTask,它显示来自外部 URL 的项目列表。

 private static class GetContacts extends AsyncTask<String, Void, List<Actors>> {
    ProgressDialog dialog;
    private final WeakReference<Search> activityReference;
    GetContacts(Search context) {
        activityReference = new WeakReference<>(context);
    }
    
    @Override
    protected void onPreExecute() {
        Search activity = activityReference.get();
        if (activity == null || activity.isFinishing() || activity.isDestroyed()) return;
        super.onPreExecute();
        dialog = new ProgressDialog(activity);
        dialog.setMessage(activity.getResources().getString(R.string.Searching));
        dialog.setTitle(activity.getResources().getString(R.string.connecting));
        dialog.show();
        dialog.setCancelable(false);
    }

    @Override
    protected  List<Actors> doInBackground(String... sText) {
        final Search activity = activityReference.get();
        List<Actors> myList = new ArrayList<>();
        HttpHandler sh = new HttpHandler();
        String url = "http://myurl?par="+sText;

        String jsonStr = sh.makeServiceCall(url);

        if (jsonStr != null) {
            try {JSONObject jsonObj = new JSONObject(jsonStr);
                JSONArray actors = jsonObj.getJSONArray("result");

                for (int i = 0; i < actors.length(); i++) {
                    JSONObject c = actors.getJSONObject(i);

                    Actors actor = new Actors();
                    actor.setNazov(c.getString("title"));
                    actor.setPerex(c.getString("perex"));

                    myList.add(actor);
                }

            }  catch (final JSONException e) {
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(activity,
                                R.string.Nodata,
                                Toast.LENGTH_LONG).show();
                    }
                }); }

                return myList;

        } else {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(activity,
                            R.string.Network,
                            Toast.LENGTH_LONG).show();
                }
            });
            return null;
        }
    }

    protected void onPostExecute(List<Actors>   result) {
        Search activity = activityReference.get();
        if (activity == null || activity.isFinishing() || activity.isDestroyed()) return;
        super.onPostExecute(result);
        if (dialog != null) {
            dialog.dismiss();  dialog = null;
        }
        activity.actorsList.clear();
         if (result!=null) { activity.actorsList.addAll(result);}
        activity.adapter.notifyDataSetChanged();
    }
}

我是这样执行的:

new GetContacts(Search.this).execute(newText,lng);

然而这仍然工作正常,AsyncTask 已从 Android11 中弃用。我已经阅读了很多关于一些替换的线程,但仍然没有找到替换我的案例的解决方案。

我尝试了它作为使用 Thread 的最简单解决方案的建议,

但这并不像预期的那样容易。存在多个问题,例如无法解析方法 'runOnUIThread(java.lang.Runnable)'、无法解析方法 'start()' 等

其实我不太清楚,如何替换整个异步任务。

1/ 有 onPreExecute(),我不确定从那里把东西放在哪里,因为我需要显示一个加载对话框。

2/ List doInBackground(String...sText) - 后台任务本身带有一个参数(String)

3/ 最后是 onPostExecute

您能否帮助解释并建议如何重新创建此代码以使其正常工作,而不是弃用的 AsyncTask? (在 Java 中,没有 Kotlin,至于 Kotlin,我也找到了一些 CoroutineScope 解决方案)

我设法做的是这样的:

 void GetContacts(final String sText) {
        try {
            Thread thread = new Thread() {
                public void run() {
                    Looper.prepare();
                    final JSONObject[] maindata = {new JSONObject()};

                    final Handler handler = new Handler(Looper.getMainLooper());
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            List<Actors> myList = new ArrayList<>();
                            HttpHandler sh = new HttpHandler();
                            String url = "https://myurl?par="+sText;

                            String jsonStr = sh.makeServiceCall(url);

                            if (jsonStr != null) {
                                try {JSONObject jsonObj = new JSONObject(jsonStr);
                                    JSONArray actors = jsonObj.getJSONArray("result");

                                    for (int i = 0; i < actors.length(); i++) {
                                        JSONObject c = actors.getJSONObject(i);

                                        Actors actor = new Actors();
                                        actor.setNazov(c.getString("title"));
                                   actor.setThumb(c.getString("thumb"));


                                        myList.add(actor);
                                    }

                                }  catch (final JSONException e) {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(getApplicationContext(),
                                                    R.string.Nodata,
                                                    Toast.LENGTH_LONG).show();
                                        }
                                    }); }

                              //  return myList;

                            } else {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(getApplicationContext(),
                                                R.string.Network,
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
                             //   return null;
                            }

                            handler.removeCallbacks(this);
                            Objects.requireNonNull(Looper.myLooper()).quit();
                        }
                    }, 2000);

                    Looper.loop();
                }
            };
            thread.start();

        } catch (Exception ex) {
            Log.e("ERROR =>", "" + ex.getMessage());
            ex.printStackTrace();
        }

    }

但是,我这里有一个错误java.lang.IllegalStateException:主线程不允许退出,这样它根本不起作用。

并且仍然缺少预执行和 post 执行内容。即使我从主线程中删除退出,列表也不会出现。

要从服务器 api 获取数据,请使用 retrofit2。很简单