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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:58:12