I have a function, and in it i am running an thread using Anonymous class, so how to return value to that function

Tags: , , ,



The code below will make it more clear:

public static String TCMResponse(String params, final Context c) {
    final String url = "https://115.248.161.106/ois/API/android/" + params;
    new Thread(new Runnable() {
        @Override
        public void run() {
            String response="";

            try {
                Document doc = Jsoup.connect(url).validateTLSCertificates(false).timeout(6000).get();
                response = doc.text();

            }
            catch (IOException e) {
                Log.d("Err","External OIS not reachable!");
            }

            // I want to return 'response' here, for the TCMResponse()
        }
    }).start();
}

So as you can see from the code, there is a function, TCMResponse() which takes the parameters of the url which i pass, and it does web scraping, i know all these can be done using volley/ JSONParser easily. But i am just experimenting, how to parse using web scraping.

So after the page is scraped, i need that function to return the response of the scraped page,

I’ve used Callable with executor service, but it again freezes the thread.. Have a look on what i’ve done:

public static String TCMResponse(String params, final Activity act) {

    StrictMode.ThreadPolicy policy = new
            StrictMode.ThreadPolicy.Builder()
            .permitAll().build();
    StrictMode.setThreadPolicy(policy);

    final String url = "https://115.248.161.106/ois/API/android/" + params;
    response="";

    class MyBgThread implements Callable<String>
    {
        @Override
        public String call() throws Exception {
            try{
                Document doc = Jsoup.connect(url).validateTLSCertificates(false).timeout(6000).get();
                return doc.text();
            }catch (Exception e)
            {
                Log.d("Exception",e.toString());
                Snackbar.with(act, null)
                        .type(Type.ERROR)
                        .message("Something got wrong!")
                        .duration(Duration.LONG)
                        .show();
                return "{'auth':'false'}";
            }
        }
    }

    Callable<String> worker = new MyBgThread();
    ExecutorService ex = Executors.newSingleThreadExecutor();
    Future<String> future = ex.submit(worker);
    try{
        response = future.get();
    }catch(Exception e)
    {
        Log.d("Thread Ex",e+"");
    }
    ex.shutdown();
    return response;
}

Answer

The main thread gets blocked because of your call to Future::get().

From the docs:

Waits if necessary for the computation to complete, and then retrieves its result.

which means; if the task Thread has not yet finished, the current Thread will wait until it returns a result.


I can see another problem in your code: you are showing a Snackbar, which is a UI component, in a Thread that is not the UI Thread.

Since you are working on Android, I would definitely use an AsyncTask, perform the expensive call in doInBackground(), then update the UI in onPostExecute().



Source: stackoverflow