Search code examples
androidandroid-asynctask

Android simple list with AsyncTask alternative


I have an AsyncTask, which shows an item list from an external 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();
    }
}

and I am executing it like this:

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

However this is still working fine, the AsyncTask is deprecated from Android 11. I have read many threads about some replacements but still did not find a solution to replace my case.

I tried as it was suggested to me as the simplest solution to use Thread,

But this is not working so easily as expected. There are multiple issues as Cannot resolve method 'runOnUIThread(java.lang.Runnable)', Cannot resolve method 'start()' etc.

Actually, I am not sure, how to replace the whole async task.

1/ There is onPreExecute() and I am not sure where to put the stuff from there, as I need to show a loading dialog.

2/ List doInBackground(String... sText) - the background task itself with a parameter (String)

3/ and finally onPostExecute

Can you please help to explain and advise how to recreate this code to bring it to work instead of deprecated AsyncTask? (in Java, no Kotlin, as for Kotlin I've found also some CoroutineScope solutions)

What I managed to do is something like this:

 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();
        }

    }

However, I have an error here java.lang.IllegalStateException: Main thread not allowed to quit and this way it doesn't work at all.

And still missing the pre and post execute stuff. Even if I remove the quit from the main thread, the list is not appearing.


Solution

  • For fetching from server api use retrofit2. It is very simple