Android 简单列表与 AsyncTask 替代
Posted
技术标签:
【中文标题】Android 简单列表与 AsyncTask 替代【英文标题】:Android simple list with AsyncTask alternative 【发布时间】:2021-02-11 07:55:04 【问题描述】:我有一个 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);
但是这仍然可以正常工作,android 11 已弃用 AsyncTask。我已经阅读了许多关于一些替换的线程,但仍然没有找到替换我的案例的解决方案。
我尝试了它作为使用 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: Main thread not allowed to quit,这样它根本不起作用。
并且仍然缺少执行前和执行后的内容。即使我从主线程中删除退出,列表也不会出现。
【问题讨论】:
【参考方案1】:要从服务器 api 获取,请使用 retrofit2。很简单
【讨论】:
谢谢,以后会注意到,但我现在不想使用其他一些库,因为我有一个动态 URL,其中参数根据输入搜索框而变化,而且我已经有了我的自己的适配器、布局和所有逻辑。 http 工作正常,我只需要替换已弃用的 AsyncTask retrofit 可以和动态url一起使用***.com/a/32559579/1791771 嗯,这对我来说是全新的,我查看了改造原始页面,但现在我更困惑它是如何工作的。我无法想象如何将我的代码转移到那里,因为我需要一条加载消息,然后根据用户在搜索字段中键入的字母刷新视图并显示结果。也许如果您可以发布一些类似于我的案例的示例,我将非常感激。我想这对您来说并不难,因为您提到它很容易:) 你应该通过 UI、ViewModel + Flow、Repo + Coroutines 将你的逻辑分层 协程不仅仅适用于 Kotlin?我对 android 比较陌生,而且正如我所写,从未使用过改造,所以我需要看一些类似的工作示例来学习。如果没有其他解决方案,将尝试在网络上寻找一些东西以上是关于Android 简单列表与 AsyncTask 替代的主要内容,如果未能解决你的问题,请参考以下文章
使用 AsyncTask 中的 onPostExecute 方法列表项单击事件调用 Android 中的另一个活动
Android中AsyncTask基本用法与源码分析(API 23)
Android中使用AsyncTask实现文件下载以及进度更新提示