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

无法从Activity调用RecyclerView Adapter方法,需后台执行数据库操作

解决AsyncTask调用Adapter方法找不到&后台数据库操作卡顿问题

我来帮你搞定这两个问题:首先是Android Studio提示找不到setdataEntries方法的报错,然后是优化后台数据库操作避免界面卡顿(顺便说下,AsyncTask已经被官方废弃了,我会给你推荐更现代的替代方案)。

一、解决“找不到setdataEntries方法”的核心问题

你在Activity里把Adapter声明成了RecyclerView.Adapter类型,而setdataEntries是你自定义的EntryAdapter里的方法,父类RecyclerView.Adapter并没有这个方法,所以编译器识别不到。

修复步骤:
把Activity里的Adapter变量声明从:

private RecyclerView.Adapter adapater;

改成:

private EntryAdapter adapater;

这样初始化的时候:

adapater = new EntryAdapter(this);
recyclerView.setAdapter(adapater);

之后在FetchDataTask的onPostExecute里调用adapater.setdataEntries(Data)就不会报错了。

二、优化后台数据库操作(替代废弃的AsyncTask)

AsyncTask在API 30已经被官方标记为废弃,而且容易引发内存泄漏,推荐使用协程来执行后台操作,这也是Room官方推荐的方式,能更安全地处理后台任务和UI更新。

1. 先把Room数据库改成单例模式(避免重复创建实例)

每次创建新的Room数据库实例会浪费资源,建议把AppDatabase改成单例:

public abstract class AppDatabase extends RoomDatabase {
    public abstract EntryDao entryDao();
    
    // 单例实例
    private static volatile AppDatabase INSTANCE;
    
    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class, "production")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

2. 用协程替换AsyncTask

删除原来的FetchDataTask内部类,修改dataView方法:

public void dataView() {
    String site= extras.getString("sitename");
    recyclerView.setVisibility(View.VISIBLE);
    mLoadingIndicator.setVisibility(View.VISIBLE);
    
    // 使用Activity的lifecycleScope,自动跟随生命周期销毁,避免内存泄漏
    lifecycleScope.launch(Dispatchers.IO) {
        try {
            // 获取单例数据库实例
            AppDatabase db = AppDatabase.getInstance(getApplicationContext());
            List<UserTuple> entries = db.entryDao().getSpecific(site);
            
            // 解密数据
            for(UserTuple ut : entries){
                Log.i("password",ut.getPassword());
                String st = new Decryption().decrypt(ut.getPassword(),key());
                Log.i("After decryption",st);
                ut.setPassword(st);
            }
            
            // 切回主线程更新UI
            withContext(Dispatchers.Main) {
                mLoadingIndicator.setVisibility(View.INVISIBLE);
                adapater.setdataEntries(entries);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 切回主线程处理错误
            withContext(Dispatchers.Main) {
                mLoadingIndicator.setVisibility(View.INVISIBLE);
                showerror();
            }
        }
    }
}

这样既避免了主线程卡顿,又解决了AsyncTask的潜在问题。

三、额外的小修复

你在onCreate里有一行代码会导致空指针:

Log.i("Logins","Size of returned list "+entries.size());

这里entries还没初始化,直接调用size()会崩溃,建议删掉这行,或者移到数据加载完成后再打印。

内容的提问来源于stack exchange,提问作者Abhimanyu Ravilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:52:28