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

Android中通过子线程修改Activity状态失效且白屏重启如何解决

问题原因
  • 子线程无限死循环占用CPU:MyThread的run方法包含无退出条件的while(true)循环,启动后会持续占用CPU资源,导致负责UI渲染和事件响应的主线程无法获得足够调度资源,最终触发ANR(应用无响应),表现为白屏、闪退重启。
  • 重复创建线程:每次点击按钮都会新建一个线程执行死循环任务,点击次数越多CPU占用越高,会加速系统杀进程的触发。
  • 内存泄漏:MyThread持有ActivityTwo的强引用,只要线程没有终止,就算ActivityTwo被销毁也无法被GC回收,持续占用内存,资源耗尽时也会导致应用崩溃。
解决方案
  • 给循环增加退出条件:新增运行状态标记,在Activity销毁时终止线程,避免无限运行。
  • 使用弱引用持有Activity实例:避免因为线程持有强引用导致的内存泄漏。
  • 避免重复启动线程:增加线程运行状态判断,防止多次点击创建多个死循环线程。
  • 保证多线程数据可见性:给myValue增加volatile修饰,保证子线程修改的值在主线程能正常读取。
修正后代码

MyThread类

public class MyThread implements Runnable {
    // 用弱引用持有Activity,避免内存泄漏
    private WeakReference<ActivityTwo> activityRef;
    // 运行状态标记,volatile保证多线程状态可见
    public volatile boolean isRunning = true;

    public MyThread(ActivityTwo activity) {
        this.activityRef = new WeakReference<>(activity);
    }

    @Override
    public void run() {
        // 增加退出条件
        while(isRunning){
            ActivityTwo activity = activityRef.get();
            // Activity已经被回收直接退出线程
            if(activity == null) {
                break;
            }
            activity.setValue(2);
            // 若不需要高频修改,可增加休眠降低CPU占用,示例:
            // try { Thread.sleep(100); } catch (InterruptedException e) { break; }
        }
    }
}

ActivityTwo类

public class ActivityTwo extends AppCompatActivity {
    private MyThread myThread;
    private Button startLogBtn;
    // volatile保证多线程下的变量可见性
    private volatile int myValue;
    // 标记线程是否已启动,避免重复创建
    private boolean threadStarted = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_two);

        startLogBtn = findViewById(R.id.startLogBtn);
        myThread = new MyThread(this);

        startLogBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 避免重复启动线程
                if(!threadStarted) {
                    new Thread(myThread).start();
                    threadStarted = true;
                }
            }
        });
   }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Activity销毁时主动终止线程释放资源
        if(myThread != null) {
            myThread.isRunning = false;
        }
   }

   public void setValue(int value){
       this.myValue= value;
   }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:24:03