Android中如何实现无限循环?代码运行无显示问题求助
问题分析与解决方案
嘿,我来帮你梳理下代码里的问题,再给你几个靠谱的改进方案~
首先,你的代码里有几个核心问题直接导致了界面无响应:
- 主线程被彻底阻塞:你在
onCreate里直接写了while(true)无限循环,还加上了Thread.sleep——Android的主线程负责UI渲染、用户交互,一旦被这种循环卡死,系统根本没法更新界面,自然看不到任何内容。 - 网络请求跑在主线程:
Jsoup.connect(myUrl).get()是网络请求,属于耗时操作,Android早就禁止在主线程做这类事,不仅会触发ANR(应用无响应),还可能直接抛出异常。 - 无效的循环逻辑:内层的
while (myArrayList.get(0).equals(myArraylist.get(0)))永远为true,因为是同一个列表的元素做比较,这会让线程一直休眠,完全达不到你想要的“间隔刷新”效果。
下面给你两个更合理的实现思路,既避免主线程阻塞,又能高效完成定时刷新需求:
方案1:用Handler + Runnable实现前台定时刷新
这是轻量级的方案,适合APP在前台运行时的定时刷新需求:
public class OpenActivity extends AppCompatActivity { ArrayList<String> myArrayList = new ArrayList<>(); CustomAdapter myAdapter; ListView list; private Handler refreshHandler = new Handler(Looper.getMainLooper()); private Runnable refreshRunnable; private static final long REFRESH_INTERVAL = 900000; // 15分钟,和你原来的休眠时间一致 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myActivity); list = findViewById(R.id.myList); // 先初始化适配器,避免重复创建 myAdapter = new CustomAdapter(this, myArrayList); list.setAdapter(myAdapter); // 定义刷新任务 refreshRunnable = new Runnable() { @Override public void run() { // 网络请求放到子线程执行 new Thread(new Runnable() { @Override public void run() { try { Document doc = Jsoup.connect(myUrl).get(); // 这里处理你获取到的信息,比如解析后添加到列表 // 更新UI必须回到主线程 runOnUiThread(new Runnable() { @Override public void run() { // 示例:假设你拿到了新数据newData // myArrayList.clear(); // myArrayList.addAll(newData); myAdapter.notifyDataSetChanged(); } }); } catch (Exception ex) { ex.printStackTrace(); // 替换成你需要的异常处理逻辑 } finally { // 不管请求成功失败,都安排下一次刷新 refreshHandler.postDelayed(refreshRunnable, REFRESH_INTERVAL); } } }).start(); } }; // 启动第一次刷新 refreshHandler.post(refreshRunnable); } @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时移除任务,避免内存泄漏 refreshHandler.removeCallbacks(refreshRunnable); } }
方案2:用WorkManager实现后台定时刷新
如果你的需求是APP在后台也需要定时刷新数据,推荐用WorkManager——这是Android官方推荐的后台任务调度工具,比已弃用的AsyncTask更可靠,也不存在所谓的“开销过大”问题:
首先添加依赖(在app模块的build.gradle的dependencies中):
implementation "androidx.work:work-runtime:2.8.1"
然后实现Worker类处理刷新逻辑:
public class RefreshDataWorker extends Worker { public RefreshDataWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @NonNull @Override public Result doWork() { try { Document doc = Jsoup.connect(myUrl).get(); // 处理数据,比如把新数据存到数据库或SharedPreferences return Result.success(); } catch (Exception ex) { ex.printStackTrace(); // 请求失败时可以设置重试 return Result.retry(); } } }
最后在Activity里调度任务并监听结果更新UI:
public class OpenActivity extends AppCompatActivity { ArrayList<String> myArrayList = new ArrayList<>(); CustomAdapter myAdapter; ListView list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myActivity); list = findViewById(R.id.myList); myAdapter = new CustomAdapter(this, myArrayList); list.setAdapter(myAdapter); // 配置每15分钟执行一次的定时任务 PeriodicWorkRequest refreshRequest = new PeriodicWorkRequest.Builder( RefreshDataWorker.class, 15, TimeUnit.MINUTES) .build(); WorkManager.getInstance(this).enqueue(refreshRequest); // 监听任务结果,更新UI WorkManager.getInstance(this).getWorkInfoByIdLiveData(refreshRequest.getId()) .observe(this, workInfo -> { if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) { // 从数据库/SharedPreferences读取最新数据,更新列表 // myArrayList.clear(); // myArrayList.addAll(newData); myAdapter.notifyDataSetChanged(); } }); } }
几个关键注意点
- 绝对不要在主线程做耗时操作:网络请求、大计算、线程休眠都必须放到子线程。
- UI更新必须在主线程:更新ListView适配器这类操作,一定要通过
runOnUiThread、Handler或者LiveData回到主线程执行。 - 避免内存泄漏:用Handler时,记得在页面销毁时移除回调;WorkManager本身是生命周期安全的,不用额外担心这个问题。
- AsyncTask已被弃用:官方早就不推荐使用它了,上面的方案不仅更稳妥,资源占用也完全在合理范围内。
内容的提问来源于stack exchange,提问作者user9702649
相关产品推荐
相关产品推荐

