android - SetListAdapter 仅在 Debug模式下工作

标签 android listview android-asynctask

我正在开发一个应用程序,该应用程序(在 AsyncTask 中)执行对远程服务器的查询以获取 JSON 字符串。 为了在我的 ListView 上显示数据,我扩展了一个 ArrayAdapter。

当我执行我的应用程序时,我可以从 LogCat 中看到数据已正确检索但未显示在 ListView 中。

我必须让一切正常工作(并且数据显示在 ListView 上)的唯一方法是在 Debug模式下运行应用程序,在行上设置断点

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"}]

这里是我扩展 ArrayList 的地方

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

}

最佳答案

你的流程中断了。它在 Debug模式下工作只是因为你在断点处停止了 UI 线程的执行,但是在断点之前的行你触发了 AsyncTask,并且由于它没有停止,它会在你享受断点的同时下载数据。您很可能假设 AsyncTask(Asynchronous Task 的缩写)是......好吧......同步的。不是。您的主代码不会等待 asynctask,它会启动并继续。您需要重新编写代码,并在 asynctask 的 onPostExecute() 方法中根据下载的内容更新您的数据集,然后在您的列表适配器上调用 notifyDatasetChanged()。那应该触发列表刷新。

关于android - SetListAdapter 仅在 Debug模式下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31864551/

相关文章:

android - 相机人脸检测坐标到屏幕坐标

android - 如何在 flutter 的 Markdown 中添加超链接到文本

java - 如何限制 Canvas 的翻译矩阵?

java - 安卓.view.InflateException : Binary XML file line #9: Error inflating class <unknown>

android - AsyncTask 强制关闭

android - 如何通过将 map 图 block 图像保存到 sqlite 数据库中来使用 osmdroid 实现离线 map ?

listview - 如何以编程方式用户根据 JavaFX 中的字符串值定义 ListView 的颜色

Android fragment 相互重叠

android - 异步任务返回空指针

javascript - Jquery Mobile Listview Clicked Item - 将参数传递给另一个页面