2016-01-16 4 views
0

Я пытаюсь использовать Rest Webservice. Поскольку я не могу выполнять сетевые операции в потоке пользовательского интерфейса, поэтому я попытался сделать это с помощью AsyncTask. Ниже мой код для моего AsyncTaskandroid.os.NetworkOnMainThreadException даже при использовании AsynTask

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() предоставляет услуги слой, который в конечном итоге вызывает ниже метод

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

Теперь я зову свою задачу от метода OnCreate моей деятельности, как показано ниже

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

Я очень новичок в разработке Android и не в состоянии выяснить, в чем проблема с вышеуказанным кодом. Пожалуйста, помогите мне. Дайте мне знать, если вам нужно больше кода для понимания.

ответ

2

Избавиться от get() вызова в конце:

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

Это блокирует главный поток приложения.

Вместо этого настройте ArrayAdapter в onPostExecute() вашего AsyncTask.

Или используйте обычную нить вместо AsyncTask и используйте шину событий для доставки результатов веб-сервиса на ваш уровень пользовательского интерфейса, как я продемонстрирую в this sample app.

Или используйте библиотеку, предлагающую новый API HTTP, как и OkHttp, что упрощает асинхронные HTTP-операции, как я продемонстрировал в this sample app.

Или переключитесь на библиотеку, такую ​​как Retrofit, что упрощает асинхронный вызов веб-сервиса REST, как я продемонстрирую в this sample app.

+0

+1 для модернизации. Никто не должен иметь дело с HttpUrlConnection напрямую, чтобы делать REST. И можем ли мы просто убить AsyncTask и хоронить его навсегда? – GreyBeardedGeek

+0

Я попытался использовать onPostExecute() для установки моего списка, а затем для заполнения моего адаптера из метода вызова. BUt в этом случае последовательность утверждений выходит из строя. Даже когда я использую Thread.sleep (3000), я получаю NullPointerException перед тем, как установить список. –

+0

@KumarGaurav: «BUt в этом случае последовательность утверждений выходит из строя». - тогда, возможно, вам следует переместить большую часть своей работы в 'onPostExecute()'. Или, возможно, вы должны использовать один из других вариантов, которые я изложил в своем ответе. – CommonsWare

Смежные вопросы