1

私の AsyncTask では、Jsoup を使用して Web ページからすべての p タグを取得し、それらを ArrayList に追加します。これをArrayAdapterが使用して画面を投稿で埋めますが、何らかの理由で ArrayList がメソッドの後にチェックするときは空です。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    newsItems = new ArrayList<String>();

    fillNewsItems();
    setListAdapter(new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1,
            newsItems));
    Log.d("news", Integer.toString(newsItems.size()));
}

private class GetNewsItemsTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {
        try {
            Document doc = Jsoup.connect(URL).get();
            for (Element e : doc.getElementsByTag("p")) {
                newsItems.add(e.text());
            }
        } catch (Exception e) {     
            Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
                    Toast.LENGTH_SHORT).show();
        }           
        return null;
    }
}

private void fillNewsItems() {
    GetNewsItemsTask getNews = new GetNewsItemsTask();
    getNews.execute(URL);
}
}

onCreate のログ ステートメントが 0 を返し、リストが空である理由を知っている人はいますか?

4

2 に答える 2

3

AsyncTaskには、現在使用しているよりも多くの可能性があります。基本的に、AsyncTask はスレッド (デフォルトでは UI 要素を変更できません) ですが、特別な機能を提供します: メソッド内の UI スレッドに同期しますonPostExecute()

したがって、これを使用して のArrayAdapter内部を設定できますAsyncTaskonPreExecute()情報ダイアログを表示するために自由に使用してください。

このコードはトリックにすべきです:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    fillNewsItems();

    Log.d("news", Integer.toString(newsItems.size()));
}

private class GetNewsItemsTask extends AsyncTask<Void, Void, ArrayList<String>> {

    protected ArrayList<String> doInBackground(Void... urls) {
        try {
            ArrayList<String> items = new ArrayList<String>();
            Document doc = Jsoup.connect(URL).get();
            for (Element e : doc.getElementsByTag("p")) {
                items.add(e.text());
            }
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
                    Toast.LENGTH_SHORT).show();
        }
        return items;
    }

    @Override
    protected void onPostExecute(ArrayList<String> items) {
        newsItems = items; // I assume that newsItems is used elsewhere.
                           // If that's not the case -> remove it
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                items));
    }
}

private void fillNewsItems() {
    GetNewsItemsTask getNews = new GetNewsItemsTask();
    getNews.execute();
}

これは、Android での非同期プログラミングに関する素晴らしいチュートリアルです: Android スレッド、ハンドラー、および AsyncTask

于 2012-09-25T21:18:37.790 に答える
1

AsyncTaskの実行がまだ完了していないことが原因である可能性があります。AsyncTaskはまさにそれ、非同期です。同時にバックグラウンドで実行されます。AsyncTaskが終了するまでコードがブロックされることを期待しているように見えますがfillNewsItems()、実際には、AsyncTaskを開始した直後にほぼすぐに戻ります。したがって、リストのサイズを取得しようとしても、それはまだゼロですが、AsyncTaskはまだ終了していません。

于 2012-09-25T20:29:42.523 に答える