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

模拟器中Google Maps Polyline绘制崩溃,报空指针异常求助

解决Google Maps Polyline绘制的NullPointerException崩溃问题

看了你的错误日志和代码,问题很明确:当你拖动颜色滑块(SeekBar)时,polyline对象还没被创建(也就是还没点击过绘制按钮),这时候调用polyline.setColor()就会触发空指针异常。

下面我们一步步排查并修复问题:

问题根源分析

从错误栈能看到,崩溃发生在MainActivity.java:149的polyline.setColor(Color.rgb(red,green,blue))这一行。此时polyline是null——因为只有点击btDraw按钮后,polyline才会被赋值为gMap.addPolyline()的返回值,而如果用户先拖动颜色滑块,这个对象还不存在。

另外你的代码还有个小问题:setWidth()方法里每次都会重新给seekWidth设置监听,这会导致重复绑定,可能引发不必要的逻辑重复。

修复方案

1. 先处理空指针,同时优化颜色设置逻辑

我们可以做两件事:

  • 在onProgressChanged里不仅判断polyline是否为空,还可以把颜色值同步保存到polylineOptions里,这样后续绘制新的Polyline时也能直接用上当前设置的颜色
  • 给polylineOptions初始化默认颜色,避免绘制时Polyline是默认黑色

2. 优化SeekBar宽度监听的绑定

把seekWidth的监听移到onCreate里,不要在setWidth()里重复绑定,避免重复监听触发。

修改后的完整代码

import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, SeekBar.OnSeekBarChangeListener {
    //初始化变量
    GoogleMap gMap;
    SeekBar seekWidth, seekBlue, seekGreen, seekRed;
    Button btClear, btDraw;
    Polyline polyline = null;
    List<LatLng> latLngList = new ArrayList<>();
    List<Marker> markerList = new ArrayList<>();
    PolylineOptions polylineOptions = null;
    int red = 0, green= 0, blue=0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定控件
        seekWidth = findViewById(R.id.seek_width);
        seekRed = findViewById(R.id.seek_red);
        seekGreen = findViewById(R.id.seek_green);
        seekBlue = findViewById(R.id.seek_blue);
        btDraw=findViewById(R.id.bt_draw);
        btClear=findViewById(R.id.bt_clear);

        //初始化SupportMapFragment
        SupportMapFragment supportMapFragment = (SupportMapFragment)getSupportFragmentManager()
                .findFragmentById(R.id.google_map);
        supportMapFragment.getMapAsync(this);

        // 把seekWidth的监听移到这里,避免重复绑定
        seekWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int width = seekWidth.getProgress();
                if (polyline != null) {
                    polyline.setWidth(width);
                }
                // 同步更新polylineOptions的宽度
                if(polylineOptions != null){
                    polylineOptions.width(width);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        btDraw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //在地图上绘制Polyline
                if (polyline!=null) polyline.remove();
                if(polylineOptions!=null){
                    // 确保polylineOptions带上当前设置的颜色
                    polylineOptions.color(Color.rgb(red, green, blue));
                    polyline = gMap.addPolyline(polylineOptions);
                    // 绘制后同步宽度
                    polyline.setWidth(seekWidth.getProgress());
                }
            }
        });

        btClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //清空所有内容
                if (polyline!=null) polyline.remove();
                for(Marker marker: markerList) marker.remove();
                latLngList.clear();
                markerList.clear();
                seekWidth.setProgress(3);
                seekBlue.setProgress(0);
                seekGreen.setProgress(0);
                seekRed.setProgress(0);
                // 重置颜色值和polylineOptions
                red = 0;
                green = 0;
                blue = 0;
                polylineOptions = null;
                polyline = null;
            }
        });

        seekRed.setOnSeekBarChangeListener(this);
        seekGreen.setOnSeekBarChangeListener(this);
        seekBlue.setOnSeekBarChangeListener(this);
    }

    public void onMapReady(GoogleMap googleMap) {
        gMap= googleMap;
        gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                //创建MarkerOptions
                MarkerOptions markerOptions = new MarkerOptions().position(latLng);
                //创建Marker
                Marker marker = gMap.addMarker(markerOptions);
                //添加坐标与Marker到列表
                latLngList.add(latLng);
                markerList.add(marker);
                // 初始化或更新polylineOptions,带上当前的颜色和宽度
                polylineOptions = new PolylineOptions()
                        .addAll(latLngList)
                        .clickable(true)
                        .color(Color.rgb(red, green, blue))
                        .width(seekWidth.getProgress());
            }
        });
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        switch (seekBar.getId()){
            case R.id.seek_red:
                red = i;
                break;
            case R.id.seek_green:
                green = i;
                break;
            case R.id.seek_blue:
                blue= i;
                break;
        }
        // 如果polyline已存在,直接修改颜色
        if(polyline !=null){
            polyline.setColor(Color.rgb(red,green,blue));
        }
        // 同步更新polylineOptions的颜色,后续绘制时生效
        if(polylineOptions != null){
            polylineOptions.color(Color.rgb(red, green, blue));
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

关键修改点说明

  • 把seekWidth的监听移到onCreate中,避免每次调用setWidth()重复绑定
  • 在onProgressChanged中,不仅修改已存在的polyline颜色,还同步更新polylineOptions的颜色,这样后续点击绘制时会直接用当前设置的颜色
  • 在onMapClick创建polylineOptions时,直接带上当前的颜色和宽度参数
  • 点击btDraw时,确保polylineOptions带上最新的颜色
  • 点击btClear时,重置polyline、polylineOptions和颜色变量,避免残留状态

这样修改后,不管用户先拖动滑块还是先绘制Polyline,都不会再触发空指针异常了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:03:29