2015-08-06 3 views
2

Я работаю над приложением, которое выполняет (в AsyncTask) запрос на удаленный сервер, получая строку JSON. Чтобы показать данные в моем ListView, я расширил ArrayAdapter.SetListAdapter работает только в режиме отладки

Когда я выполняю свое приложение, из LogCat я вижу, что данные извлекаются правильно, но не показаны в ListView.

Единственный способ, которым я должен сделать все работы (и данные будут показаны на ListView) является запуск приложения в режиме отладки, установить контрольную точку на линии

MyListView. setAdapter (myAdapter);

подождите несколько секунд, а затем возобновите приложение. После этой процедуры все работает правильно.

Почему это происходит?

Является ли AsyncTask правильным способом для такой длительной операции, или мне нужно использовать какой-либо другой подход (но я не знаю, какой именно!).

Вот код MainActivity

public class MainActivityFragment extends Fragment { 

private List<Station> stationList = new ArrayList<Station>(); 
private StationAdapter stationsAdapter; 
private ProgressDialog pd; 
private String LOG_TAG = "ProvaAsyncTask"; 

public MainActivityFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

    mioAsync mioTask = new mioAsync(); 
    mioTask.execute(); 


    stationsAdapter = new StationAdapter(stationList, getActivity()); 

    ListView stationsListView = (ListView) rootView.findViewById(R.id.miaListView); 

    stationsListView.setAdapter(stationsAdapter); 

    return rootView; 
} 


public class mioAsync extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

     // Creo la ProgressDialog che precede il caricamento dei dati 
     pd = new ProgressDialog(getActivity()); 
     pd.setMessage(MainActivityFragment.this.getString(R.string.preloader_stations_list)); 
     pd.show(); 
    } 


    @Override 
    protected Void doInBackground(Void... params) { 

     HttpURLConnection urlConnection = null; 
     BufferedReader reader = null; 

     String forecastJsonStr = null; 

     try { 

      URL url = new URL("*remoteserver*"); 

      // Create the request to the server, and open the connection 
      urlConnection = (HttpURLConnection) url.openConnection(); 
      urlConnection.setRequestMethod("GET"); 
      urlConnection.connect(); 

      // Read the input stream into a String 
      InputStream inputStream = urlConnection.getInputStream(); 
      StringBuffer buffer = new StringBuffer(); 
      if (inputStream == null) { 
       // Nothing to do. 
       return null; 
      } 
      reader = new BufferedReader(new InputStreamReader(inputStream)); 

      String line; 
      while ((line = reader.readLine()) != null) {      
       buffer.append(line + "\n"); 
      } 

      if (buffer.length() == 0) { 
       // Stream was empty. No point in parsing. 
       return null; 
      } 
      forecastJsonStr = buffer.toString(); 

     } catch (IOException e) { 
      Log.e(LOG_TAG, "Error ", e);     
      return null; 
     } finally{ 
      if (urlConnection != null) { 
       urlConnection.disconnect(); 
      } 
      if (reader != null) { 
       try { 
        reader.close(); 
       } catch (final IOException e) { 
        Log.e(LOG_TAG, "Error closing stream", e); 
       } 
      } 
     } 

     try{ 
      getStationsListFromJson(forecastJsonStr); 

     } catch (JSONException e) { 
      Log.e(LOG_TAG, e.getMessage(), e); 
      e.printStackTrace(); 
     } 

     return null; 

    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     pd.dismiss(); 
    } 


    private void getStationsListFromJson(String stationsJsonStr) throws JSONException { 

     JSONArray stationsArray = new JSONArray(stationsJsonStr); 

     String nomeStaz; 
     String numSat; 

     stationList.clear(); 
     for (int i = 0; i < stationsArray.length(); i++) { 
      JSONObject j = stationsArray.optJSONObject(i); 
      Iterator it = j.keys(); 

      while (it.hasNext()) { 
       String n = it.next().toString(); 
       numSat = j.getString(n) + " stazioni"; 
       n = it.next().toString(); 
       nomeStaz = j.getString(n); 
       stationList.add(new Station(nomeStaz, numSat)); 
      } 
     } 

    } 

} 
} 

Строка JSON я получаю в ответ, как это

[{"nome":"Station1","satelliti":"11"},{"nome":"Station2","satelliti":"9"},{"nome":"Station3","satelliti":"8"}] 

Вот где я продлите Список_массивов

public class StationAdapter extends ArrayAdapter<Station> { 

private List<Station> stationsList; 
private Context context; 

public StationAdapter(List<Station> lista, Context cont){ 
    super(cont, R.layout.listitems, lista); 
    this.stationsList = lista; 
    this.context = cont; 
} 

public int getCount() { 
    return stationsList.size(); 
} 

public Station getItem(int position) { 
    return stationsList.get(position); 
} 

public long getItemId(int position) { 
    return stationsList.get(position).hashCode(); 
} 

public View getView(int position, View convertView, ViewGroup parent){ 
    View v = convertView; 

    StationHolder holder = new StationHolder(); 

    // controllo che il convertview non sia null 
    if (convertView == null){ 

     // This a new view we inflate the new layout 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.listitems, null); 

     // Now we can fill the layout with the right values 
     TextView stationName = (TextView) v.findViewById(R.id.testataUno); 
     TextView satellitesNumber = (TextView) v.findViewById(R.id.testataDue); 

     holder.stationNameView = stationName; 
     holder.satellitesNumberView = satellitesNumber; 

     v.setTag(holder); 



    } else { 
     holder = (StationHolder) v.getTag(); 
    } 

    Station p = stationsList.get(position); 
    holder.stationNameView.setText(p.getName()); 
    holder.satellitesNumberView.setText("" + p.getSatellites()); 

    return v; 
} 


/* ********************************* 
* We use the holder pattern 
* It makes the view faster and avoid finding the component 
* **********************************/ 

private static class StationHolder { 
    public TextView stationNameView; 
    public TextView satellitesNumberView; 
} 

} 

здесь является Код станции

public class Station { 

private String name; 
private String satellites; 

public Station(String nome, String satelliti){ 
    this.name = nome; 
    this.satellites = satelliti; 
} 

public String getName(){ 
    return this.name; 
} 

public String getSatellites(){ 
    return this.satellites; 
} 

public void setName(String nome){ 
    this.name = nome; 
} 

public void setSatellites(String satelliti){ 
    this.satellites = satelliti; 
} 

} 
+1

необходимо указать код –

+0

Введите код – gargiolas

ответ

2

У вас сломан поток. Он работает в режиме отладки только потому, что вы прекратите выполнение потока пользовательского интерфейса на вашей точке останова, но до того, как вы остановите свою точку останова, вы запустили AsyncTask, и поскольку это не остановлено, оно загружает данные, пока вам нравится ваша точка останова. Вы, скорее всего, предположили, что AsyncTask (который является аббревиатурой от Асинхронный Задача) ... хорошо ... синхронно. Это не. Ваш основной код не будет ждать asynctask, он запустит его и продолжит. Вам необходимо переработать код, а в методе onPostExecute() в asynctask обновите свой набор данных на основе загруженного контента, а затем позвоните по номеру notifyDatasetChanged() в адаптер вашего списка. Это должно вызвать обновление списка.

+0

thank you Marcin! Как вы упомянули, я не использовал AsyncTask правильно! Мне пришлось добавить myListView.setAdapter (myAdapter) также в метод onPostExecute(), и все работает. – gargiolas

+0

вам не нужно повторно устанавливать адаптер, так как notifydatasetchanged() должно быть достаточным, если все сделано правильно –

+0

еще раз спасибо. Он работает только с помощью метода notifydatasetchange() – gargiolas

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