1

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.

Deep Parsania
  • 253
  • 2
  • 12
Darksymphony
  • 2,155
  • 30
  • 54

1 Answers1

2

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

  • thanks, will note that for future, but I don't want to use some other libraries for now, as I have a dynamic URL where the parameter changes according the input searchbox, and I already have my own adapters, layouts and all logic. The http is working fine, I just need to replace the AsyncTask as it is deprecated – Darksymphony Oct 28 '20 at 22:03
  • retrofit can be used with dynamic url https://stackoverflow.com/a/32559579/1791771 – Rustam Samandarov Oct 28 '20 at 22:07
  • well, this is something absolutely new for me, I looked to the retrofit original page, but I am more confused now how it works. I can't imagine how to transfer my code to that, as I need a loading message and then refreshing view and showing results according the user typed letters in searchfield. Maybe if you can post some example similar to my case, I will be very grateful.I suppose it is not that hard for you as you mentioned it is very easy :) – Darksymphony Oct 28 '20 at 22:50
  • You should divide your logic to layers via UI, ViewModel + Flow, Repo + Coroutines – Rustam Samandarov Oct 29 '20 at 03:05
  • Coroutines aren't for Kotlin only? I am relatively new to android, and as I wrote, never used retrofit, so I need to see some similar working example to learn. Will try to look for something on the web, if there is no other solution – Darksymphony Oct 29 '20 at 13:13
  • So I learned something about retrofit and I reworked the logic of my app, now it is working. Thank you for the advise – Darksymphony Oct 31 '20 at 23:02