android - 从 AsyncTask 内部动态更新 RecycleView
问题描述
我有以下代码:
protected void onCreate(Bundle savedInstanceState) {
RecyclerView recyclerView;
DeviceAdapter deviceAdapter;
List<Device> deviceList;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = this;
g.IP = cf.getIP(this);
g.subNet = g.IP.substring(0, g.IP.lastIndexOf(".") + 1);
deviceList = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
for(int i = 1; i < 256; i++) {
if(cf.isUp(g.subNet + i, 80)) {
deviceList.add(new Device(g.subNet + i, "PAUSED", "N/A"));
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
deviceAdapter = new DeviceAdapter(context, deviceList);
recyclerView.setAdapter(deviceAdapter);
}
}.execute();
}
它会检查主机是否在线,以及它们的端口 80 是否打开,然后在扫描结束时将它们全部添加到RecyclerView
.
我想知道如何添加:
deviceAdapter = new DeviceAdapter(context, deviceList);
recyclerView.setAdapter(deviceAdapter);
到doInBackground()
if 语句,像这样:
@Override
protected Void doInBackground(Void... params) {
for(int i = 1; i < 256; i++) {
if(cf.isUp(g.subNet + i, 80)) {
deviceList.add(new Device(g.subNet + i, "UP", "OPEN"));
deviceAdapter = new DeviceAdapter(context, deviceList);
recyclerView.setAdapter(deviceAdapter);
}
}
return null;
}
但不会使我的应用程序崩溃,以便RecyclerView
在将新项目添加到时立即更新deviceList<>
,而不是在任务完成时立即更新。
解决方案
您的应用程序正在崩溃,因为只有主线程可以处理 UI 元素,例如RecyclerView
. AsyncTask
因此,您需要做的是创建一个侦听器,每当您找到新设备时都会调用该侦听器。
例子:
public interface OnDeviceFoundListener {
void onDeviceFound(Device device);
}
@Override
protected void doInBackground(Void... params) {
for (int i = 1; i < 256; i++) {
if (cf.isUp(g.subNet + 1, 80)) {
listener.onDeviceFound(new Device(g.subNet + 1, "UP", "OPEN"));
}
}
}
然后,在RecyclerView所在的Activity或者Fragment中,你会实现这个监听接口,例如:
public class MyActivity extends AppCompatActivity implements OnDeviceFoundListener {
private List<Device> devices;
@Override
public void onDeviceFound(Device device) {
devices.add(device);
deviceAdapter = new DeviceAdapter(context, devices);
recyclerView.setAdapter(adapter);
recyclerView.getAdapter().notifyDataSetChanged();
}
}
notifyDataSetChanged
添加新设备后,不要忘记调用适配器中的方法。
推荐阅读
- c - 在 C 中的数组中输入、查找和删除字符串
- c++ - 如何从找到的字符串中获取子字符串到 C++ 中的字符?
- reactjs - React JS 和 Redux:useSelector() 与 useStore()
- android - 蓝牙经典扫描不显示设备
- get - 到 Windows 10 事件/消息的 IP 电话操作 URL (HTTP GET)
- swift - iOS Swift - 在该模型中更改属性后读取持久数据模型
- apache-spark - 如何将 Spark 结构化流数据重置为最后可用的偏移量
- python - 尝试为 MySQL-python 安装安装
- video - FFMPEG hwaccel 将 WEBM 转换为 MP4 视频失败:找不到编解码器参数
- javascript - 映射数组对象的问题