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

Android短信应用ANR问题及RecyclerView不更新求助

嘿,我来帮你拆解下你遇到的问题——RecyclerView只显示dummy数据还触发ANR,其实核心根源你自己已经发现了,咱们再把细节和优化点理清楚:

核心问题1:数据库事务未正确结束(直接引发ANR)

你在onPostExecute()里错误地调用了db1.startTransaction();,但数据库事务启动后如果不调用endTransaction()(或者先标记事务成功),会一直持有数据库锁,直接阻塞主线程,最终触发ANR。你替换成db1.endTransaction()后恢复正常,这正是最关键的修复点。

这里给你补一个标准的数据库事务写法,避免以后再踩坑:

db1.startTransaction();
try {
    // 执行你的数据库写入/修改操作
    db1.setTransactionSuccessful(); // 标记事务执行成功
} finally {
    db1.endTransaction(); // 无论成功失败,必须结束事务释放锁
}

你这次是在读取数据完成后错误启动了事务却不结束,直接把数据库资源占死,导致主线程卡死。

核心问题2:RecyclerView数据更新效率低下(加重主线程负担)

你的SmsAdapter.insert()方法每次添加一条短信就调用notifyDataSetChanged(),这会让RecyclerView整个列表重新刷新一遍,当短信数量多的时候,不仅会让UI卡顿,还会加重主线程的负担,间接加剧ANR的风险。

给你两个优化方案:

方案一:批量插入(推荐)

给Adapter加一个批量添加数据的方法,一次性刷新新增的条目范围:

public class SmsAdapter extends RecyclerView.Adapter<SmsAdapter.SmsViewHolder>{
    // ... 原有代码 ...

    public void addAll(ArrayList<String> newMessages) {
        int startPos = sms_messages_list.size();
        sms_messages_list.addAll(newMessages);
        notifyItemRangeInserted(startPos, newMessages.size());
    }
}

然后在onPostExecute()里直接调用这个方法,代替循环插入:

@Override
protected void onPostExecute(ArrayList<String> msg_list) {
    super.onPostExecute(msg_list);
    MainActivity activity = activityWeakReference.get();
    if (activity == null || activity.isFinishing()) {
        return;
    }
    try {
        activity.sms_adapter.addAll(msg_list);
    } catch (Exception e){
        Log.d(TAG, "onPostExecute: exception : " + e);
    }
    db1.endTransaction(); // 这里用正确的结束事务方法
    db1.close();
}

方案二:逐条插入但精准刷新

如果一定要保持逐条插入的逻辑,把notifyDataSetChanged()替换成notifyItemInserted(position),这样只会刷新新增的那一条,而不是整个列表:

public void insert(int position, String new_sms) {
    Log.d(TAG, "SmsAdapter: insert(): adding a new message at position + " + position);
    sms_messages_list.add(position, new_sms);
    notifyItemInserted(position); // 替换notifyDataSetChanged()
}
额外规范建议

初始化RecyclerView的时候,建议先设置LayoutManager再设置Adapter,这是更规范的写法,避免潜在的布局异常:

messages.setLayoutManager(new LinearLayoutManager(this));
sms_adapter = new SmsAdapter(this, sms_messages_list);
messages.setAdapter(sms_adapter);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:27:55