0

I am trying to consume a Rest Webservice. As i can not perform network operations in UI thread so i tried doing this using AsyncTask. Below is my code for my AsyncTask

    public class CallMeServiceAsyncTask extends AsyncTask<String, Void, List<Service>> {
    @Override
    protected List<Service> doInBackground(String... params) {
        CallmeService service= ServiceFactory.getCallmeService();
        List<Service> services= service.getAllServices(); //Calls web service and Parses Json Response
        return services;
    }
   }

CallmeService.getAllService() provides a service layer which eventually calls below method

public static String makeRestRequest(String url) throws MalformedURLException,IOException {
        String response="";
        URL restUrl= new URL(url);
        HttpURLConnection connection=(HttpURLConnection)restUrl.openConnection();
        InputStream is=new BufferedInputStream(connection.getInputStream());
        response=convertStreamToString(is);
        return response;
    }

Now i am calling my task from onCreate method of my activity as below

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        setContentView(R.layout.activity_home);
        this.optionsList=(ListView)findViewById(R.id.optionsList);

        //String[] options={"Teacher","Plumber","Electricians"};
        ArrayAdapter adapter=getServiceMenu();
        this.optionsList.setAdapter(adapter);
        optionsList.setOnItemClickListener(this);
    }
    private ArrayAdapter getServiceMenu()
    {
        ArrayAdapter adapter= null;
        try {
            List<Service> menuServices= new CallMeServiceAsyncTask().execute("").get();

            adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, menuServices);
        }
        catch(Exception x)
        {
            x.printStackTrace();
        }
        return adapter;
    }

I am very new to android development and not able to figure out what is the issue with above code. Please help me out. Let me know if you need more code to understand.

Kumar Gaurav
  • 1,287
  • 3
  • 19
  • 47

1 Answers1

2

Get rid of the get() call at the end of:

new CallMeServiceAsyncTask().execute("").get();

That is blocking the main application thread.

Instead, set up your ArrayAdapter in onPostExecute() of your AsyncTask.

Or, use an ordinary thread instead of an AsyncTask, and use a event bus to deliver the Web service results to your UI layer, as I demonstrate in this sample app.

Or, use a library offering a newer HTTP API, as does OkHttp, that makes asynchronous HTTP operations easier, as I demonstrate in this sample app.

Or, switch to a library like Retrofit, which makes asynchronous REST Web service calls easier, as I demonstrate in this sample app.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • +1 for Retrofit. Nobody should be dealing with HttpUrlConnection directly to do REST any more. And can we just kill AsyncTask and bury it for good? – GreyBeardedGeek Jan 16 '16 at 13:41
  • I tried using onPostExecute() for setting my list and later on populating my adapter from calling method. BUt in that case sequence of statements goes out of order. Even when i use Thread.sleep(3000) i get NullPointerException before i set the list. – Kumar Gaurav Jan 16 '16 at 16:03
  • @KumarGaurav: "BUt in that case sequence of statements goes out of order." -- then perhaps you should be moving more of your work into `onPostExecute()`. Or, perhaps you should be using one of the other options that I outlined in my answer. – CommonsWare Jan 16 '16 at 16:17