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

Android中While循环内CountDownTimer未执行及TextView空指针问题

Android 定时获取GPS位置的问题解决

问题1:CountDownTimer未执行(无"in timer 2"输出)

原因

你在onCreate方法里写了while(true)死循环,而onCreate运行在Android的**主线程(UI线程)**中。主线程依赖Looper处理消息队列,CountDownTimer的onFinish、onTick等回调都是通过这个消息队列分发的。死循环会完全占用主线程,导致消息队列无法处理任何后续消息,CountDownTimer的定时任务自然永远不会触发。

解决方法

彻底移除死循环,改用Android推荐的定时任务实现方式,比如Handler.postDelayed、协程或者ScheduledExecutorService,绝对不能在主线程中使用死循环阻塞线程。


问题2:tv1.append抛出NullPointerException

原因

有两种常见触发场景:

  1. 布局加载顺序错误:你在调用setContentView(R.layout.xxx)之前就执行了tv1 = findViewById(R.id.tv1),此时布局还未加载到内存中,findViewById会返回null,调用append方法就会触发空指针异常。
  2. 主线程被阻塞:即使findViewById在setContentView之后执行,while(true)死循环会阻塞主线程,导致UI布局无法完成渲染,tv1的实例并未被正确初始化,最终同样引发空指针。

解决方法

  • 确保setContentView在findViewById之前执行,先加载布局再获取控件实例;
  • 移除阻塞主线程的死循环,让UI线程能正常处理视图渲染和消息分发。

修正后的代码示例

用Handler实现每隔1秒获取GPS位置的逻辑,同时避免主线程阻塞:

private TextView tv1;
private FusedLocationProviderClient fusedLocationClient;
private CancellationTokenSource cancellationTokenSource;
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable locationRunnable;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 第一步:加载布局
    setContentView(R.layout.your_layout);
    // 第二步:获取TextView实例
    tv1 = findViewById(R.id.tv1);

    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    cancellationTokenSource = new CancellationTokenSource();

    // 定义定时执行的任务
    locationRunnable = new Runnable() {
        @SuppressLint("MissingPermission")
        @Override
        public void run() {
            fusedLocationClient.getCurrentLocation(LocationRequest.QUALITY_HIGH_ACCURACY, cancellationTokenSource.getToken())
                    .addOnSuccessListener(location -> {
                        if (location != null) {
                            double latitude = location.getLatitude();
                            double longitude = location.getLongitude();
                            System.out.println("LOCATION ACQUIRED!!!!!!! 纬度:" + latitude + " 经度:" + longitude);
                            tv1.append("纬度:" + latitude + " 经度:" + longitude + "\n");
                        } else {
                            System.out.println("LOCATION IS NULL");
                            tv1.append("未获取到位置\n");
                        }
                    })
                    .addOnFailureListener(e -> {
                        System.out.println("LOCATION FAILED!!!!!!!!! " + e.getMessage());
                        tv1.append("获取位置失败:" + e.getMessage() + "\n");
                    });

            // 每隔1秒重复执行当前任务
            handler.postDelayed(this, 1000);
        }
    };

    // 启动定时任务
    handler.post(locationRunnable);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // 页面销毁时取消定时任务和令牌,避免内存泄漏
    handler.removeCallbacks(locationRunnable);
    cancellationTokenSource.cancel();
}

额外注意事项

  • 确保已在AndroidManifest.xml中声明位置权限:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>(或ACCESS_COARSE_LOCATION),且在运行时动态申请了权限(Android 6.0及以上版本要求);
  • 不要在主线程中执行任何耗时操作,否则会触发ANR(应用无响应)弹窗;
  • 使用FusedLocationProviderClient时,务必在页面销毁时取消CancellationToken,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:57:10