You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AsyncTask中将Jsoup获取的数据设置到RecyclerView

如何通过AsyncTask将Jsoup获取的数据绑定到RecyclerView

首先,你不用非要把MyAsyncTask改成公共类,把它作为MainActivity的内部类会更方便——这样它可以直接访问Activity中的RecyclerView实例和适配器对象,省去很多回调逻辑的麻烦。下面结合你提到的几个文件,一步步拆解实现方案:

1. 先确认基础数据结构与适配器

确保你的ListItem类已经定义好存储标题的字段:

public class ListItem {
    private String title;

    public ListItem(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

MyRecViewAdapter需要提供更新数据的方法,方便后续异步任务完成后刷新列表:

public class MyRecViewAdapter extends RecyclerView.Adapter<MyRecViewAdapter.ViewHolder> {
    private List<ListItem> itemList;

    public MyRecViewAdapter(List<ListItem> itemList) {
        this.itemList = itemList;
    }

    // 用于更新数据的核心方法
    public void updateData(List<ListItem> newList) {
        itemList.clear();
        itemList.addAll(newList);
        notifyDataSetChanged();
    }

    // 以下是常规ViewHolder与重写方法,按你的布局实现即可
    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView titleTv;

        public ViewHolder(View itemView) {
            super(itemView);
            titleTv = itemView.findViewById(R.id.title_textview);
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.titleTv.setText(itemList.get(position).getTitle());
    }

    @Override
    public int getItemCount() {
        return itemList.size();
    }
}

2. 在MainActivity中实现内部类AsyncTask

在MainActivity里初始化RecyclerView后,编写内部类MyAsyncTask执行Jsoup解析,解析完成后直接调用适配器的更新方法:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private MyRecViewAdapter adapter;
    private List<ListItem> itemList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化RecyclerView
        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MyRecViewAdapter(itemList);
        recyclerView.setAdapter(adapter);

        // 启动异步任务解析网页标题
        new MyAsyncTask().execute("你的目标网页URL");
    }

    // 内部类AsyncTask,泛型参数分别对应:输入参数类型、进度更新类型、返回结果类型
    private class MyAsyncTask extends AsyncTask<String, Void, List<ListItem>> {

        @Override
        protected List<ListItem> doInBackground(String... urls) {
            List<ListItem> resultList = new ArrayList<>();
            String targetUrl = urls[0];
            try {
                // Jsoup网络请求必须在子线程执行(doInBackground)
                Document doc = Jsoup.connect(targetUrl).get();
                // 这里根据你要抓取的标题选择器调整,比如抓取所有h2标签的文本
                Elements titleElements = doc.select("h2");
                for (Element element : titleElements) {
                    resultList.add(new ListItem(element.text()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return resultList;
        }

        @Override
        protected void onPostExecute(List<ListItem> resultList) {
            super.onPostExecute(resultList);
            // 解析完成后,在主线程更新适配器数据
            adapter.updateData(resultList);
        }
    }
}

3. 关于是否将AsyncTask改为公共类的问题

如果你的异步解析逻辑需要在多个Activity中复用,改成公共类是可行的,但此时需要通过接口回调传递数据(因为公共类无法直接访问Activity的成员)。举个简单的实现例子:

首先定义回调接口:

public interface OnDataLoadedListener {
    void onDataLoaded(List<ListItem> data);
}

然后编写公共类AsyncTask:

public class MyAsyncTask extends AsyncTask<String, Void, List<ListItem>> {
    private OnDataLoadedListener listener;

    public MyAsyncTask(OnDataLoadedListener listener) {
        this.listener = listener;
    }

    @Override
    protected List<ListItem> doInBackground(String... urls) {
        // 解析逻辑和之前一致,省略
    }

    @Override
    protected void onPostExecute(List<ListItem> resultList) {
        super.onPostExecute(resultList);
        if (listener != null) {
            listener.onDataLoaded(resultList);
        }
    }
}

最后在MainActivity中调用:

new MyAsyncTask(new OnDataLoadedListener() {
    @Override
    public void onDataLoaded(List<ListItem> data) {
        adapter.updateData(data);
    }
}).execute("你的目标网页URL");

但如果只是在当前MainActivity中使用,内部类的方式会更简洁,不需要额外的回调逻辑。

必加注意事项

  • 别忘了在AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • 若目标网站是HTTP协议(非HTTPS),Android 11及以上需要在application标签中添加android:usesCleartextTraffic="true"允许明文流量

内容的提问来源于stack exchange,提问作者Сергей

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:27:41