RecyclerView加载FTP数据不显示,需锁屏解锁后才显示的问题求助
嘿,我帮你定位到问题啦!咱们一步步来解决这个RecyclerView启动不显示FTP数据的问题~
问题根源
你遇到的核心问题是在后台线程里执行了UI更新操作。AsyncTask的doInBackground()方法是跑在子线程的,而adapter.notifyDataSetChanged()属于UI操作,必须在主线程(也就是UI线程)里调用才行。之前你在子线程调用这个方法,系统不会立即刷新UI,而锁屏再解锁的操作会触发UI的重新绘制,这时候数据才会显示出来。
修复方案
我们只需要把UI更新的代码移到安全的地方,再优化几个小细节就搞定了:
1. 调整AsyncTask的UI更新逻辑
把notifyDataSetChanged()移到AsyncTask的onPostExecute()方法里——这个方法是专门在主线程执行的,完全安全。另外我们可以优化一下数据加载的逻辑,避免重复添加数据:
修改后的setUpList代码:
public class setUpList extends AsyncTask<Object, Void, Boolean> { String host = "test.rebex.net", username = "demo", password = "password"; int port = 21; @Override protected Boolean doInBackground(Object[] objects) { try { mFTPClient = new FTPClient(); // 连接FTP服务器 mFTPClient.connect(host, port); // 检查连接是否成功 if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) { Log.v("wwww", "Connected"); // 登录服务器 boolean loginStatus = mFTPClient.login(username, password); mFTPClient.setFileType(FTP.BINARY_FILE_TYPE); mFTPClient.enterLocalPassiveMode(); try { FTPFile[] ftpDirs = mFTPClient.listFiles("/pub/example/"); // 先清空列表,防止重复加载数据 fileList.clear(); for (FTPFile ftpFile : ftpDirs) { Log.d("CONNECT", "FTP服务器中的目录:" + ftpFile.getName()); fileList.add(new FileListObject(ftpFile.getName())); } return loginStatus; } catch (Exception e) { e.printStackTrace(); return false; } } } catch (Exception e) { e.printStackTrace(); return false; } return false; } @Override protected void onPostExecute(Boolean success) { super.onPostExecute(success); if (success) { // 在主线程通知适配器更新数据 adapter.notifyDataSetChanged(); } else { Toast.makeText(getApplicationContext(), "加载FTP数据失败", Toast.LENGTH_SHORT).show(); } } }
2. 优化屏幕旋转时的Adapter处理(可选)
在onConfigurationChanged()方法里,你不需要重新创建Adapter——因为Adapter已经持有了全局fileList的引用,直接复用原来的Adapter就好,减少不必要的对象创建:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); Log.v("rec", "in recycler"); // 直接通知适配器更新即可,不用重新创建 adapter.notifyDataSetChanged(); }
3. 调整RecyclerView的高度设置
你的activity_main.xml里RecyclerView的高度是wrap_content,如果数据多的话可能显示不全,建议改成match_parent:
<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recycler_view"/>
为什么这样改能解决问题?
onPostExecute()是AsyncTask中专门在主线程执行的方法,在这里调用notifyDataSetChanged()能保证UI线程安全,让RecyclerView立即刷新显示数据。- 清空
fileList再添加新数据,能避免比如屏幕旋转时重复加载数据的问题。 - 复用现有Adapter,减少内存开销,提升性能。
内容的提问来源于stack exchange,提问作者Nishant Patel
相关产品推荐
相关产品推荐

