0

LoadXMLData というAsyncTaskクラスがあり、ご覧のとおり、 doInBackground()メソッドで XML データを解析しています。

public class LoadXMLData extends AsyncTask<String, RSSFeed, RSSFeed>{

public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;


private Context context;
RSSFeed feed;



public LoadXMLData(Context context) {
    this.context = context;
    mProgressDialog = new ProgressDialog(context);
    mProgressDialog.setMessage("Molimo Vas, sačekajte. Podaci se učitavaju.");
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    mProgressDialog.show();
    Log.d("OVDE SAM:", "onPreExecute()");
}

@Override
protected RSSFeed doInBackground(String... urls) {
    // Obtain feed
    DOMParser myParser = new DOMParser();
    feed = myParser.parseXml(urls[0]);
    Log.d("OVDE SAM:", "PARSIRAM XML");
    return feed;
}



@Override
protected void onPostExecute(RSSFeed result) {
    mProgressDialog.dismiss();

    super.onPostExecute(result);
}

}

そして、その AsyncTask からデータを取得する必要があるフラグメントはほとんどありません。どうすればそれができますか?

NajnovijeFragmentというフラグメントのコードを次に示します。

public class NajnovijeFragment extends Fragment{

GridView lv;
RSSFeed feed;
CustomListAdapter adapter;
private String RSSFEEDURL = "http://balkanandroid.com/feed/";

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_najnovije, container,
            false);     


    lv = (GridView) view.findViewById(R.id.GridView1);

    // Set an Adapter to the ListView
    adapter = new CustomListAdapter();
    lv.setAdapter(adapter);

    // Set on item click listener to the ListView
    lv.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // actions to be performed when a list item clicked
            int pos = arg2;

            Bundle bundle = new Bundle();
            bundle.putSerializable("feed", feed);
            Intent intent = new Intent(getActivity(), DetailsActivity.class);
            intent.putExtras(bundle);
            intent.putExtra("pos", pos);
            startActivity(intent);

        }
    });

    return view;
}

@Override
public void onDestroy() {
    super.onDestroy();
    adapter.imageLoader.clearCache();
    adapter.notifyDataSetChanged();
}

class CustomListAdapter extends BaseAdapter {

    private LayoutInflater layoutInflater;
    public ImageLoader imageLoader;

    public CustomListAdapter() {

        layoutInflater = (LayoutInflater) getActivity().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(getActivity().getApplicationContext());
    }

    public int getCount() {
        // TODO Auto-generated method stub
        // Set the total list item count
        return feed.getItemCount();
    }

    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // Inflate the item layout and set the views
        View listItem = convertView;
        int pos = position;
        if (listItem == null) {
            listItem = layoutInflater.inflate(R.layout.list_item, null);
        }

        // Initialize the views in the layout
        ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);
        TextView tvTitle = (TextView) listItem.findViewById(R.id.title);
        TextView tvDate = (TextView) listItem.findViewById(R.id.tvDate);

        // Set the views in the layout
        imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv);
        tvTitle.setText(feed.getItem(pos).getTitle());
        tvDate.setText(feed.getItem(pos).getDate());

        return listItem;
    }

}

}

4

3 に答える 3

4

ASyncTask からデータを取得する最も簡単な方法は、コールバックを実装することです。

インターフェイスを作成します。

public interface OnXMLLoadFinishedListener {
  public void onXMLDataReady(RSSFeed results);
}

あなたのLoadXMLDataで:

private OnXMLLoadFinishedListener listener;

public void setOnXMLLoadFinishedListener(OnXMLLoadFinishedListener listener){
  this.listener = listener;
}

@Override
protected void onPostExecute(RSSFeed result) {
    super.onPostExecute(result);
    listener.onXMLDataReady(RSSFeed results);
}

あなたのフラグメントで:

public class NajnovijeFragment extends Fragment implements OnXMLLoadFinishedListener{

onXMLDataReady をオーバーライドします。

@override
public void onXMLDataReady(RSSFeed results){
   //display your data.
}

AsyncTask インスタンスを作成するときにリスナーを設定していることを確認してください。そうしないと、これは機能しません。

LoadXMLData xmlLoader = new LoadXMLData();
xmlLoader.setOnXMLLoadFinishedListener(this);
于 2013-07-11T01:35:55.940 に答える
1

AsyncTask は、UI に非常に関連するクラスです。この XML 解析で UI を更新する必要がある場合は、次の点を考慮する必要があります。

  • asynctask をフラグメントの内部クラスにするか、
  • フラグメントを asynctask に渡します
  • onPostExecute() でフラグメントのビューを更新します

いずれにせよ、アクティビティが null かどうかを確認する必要があります。そうであれば、ビューの更新を避けてください。

onPostExecute(Object xml) {
   if(getActivity != null) {
      // update Views like...
      textViewLabel.setText(parsedXml.getTitle);
   }
}

Roboguice プロジェクトの Java クラスである SafeAsyncTask を使用することをお勧めします。ファイルは 1 つだけで、java.util.concurrent.Callable に関連しています。ソースをコピーして貼り付けるだけです。

SafeAsyncTask.java

それの使い方!

于 2013-07-10T15:09:23.750 に答える
1

AsyncTask は既にコンテキストを認識しているため、onPostExecute でアクティビティ (説明のために ActivityMain と呼ばれます) にコールバックできます。例えば

@Override
protected void onPostExecute(String result) {
 super.onPostExecute(result);
 ((ActivityMain) context).loadCompleteHandler(param1,param2,...)
}

アクティビティに loadCompleteHandler をどのように実装するかは、あなた次第です。アクティビティが存在しない可能性があるため、アクティビティが削除されたときに AsyncTask をキャンセルするように注意する必要があります。アクティビティに属するフラグメントもアクティビティにアクセスできます。

于 2013-07-10T15:21:25.897 に答える