首页 > 解决方案 > 当我离开这个片段并重新输入我的 LatLng 时找不到。抛出 np ......是的,我知道 np 是什么......也许这是一个生命周期问题?

问题描述

我需要使用我FINE LOCATION的应用程序中的一项功能。我知道是什么null pointers,我意识到这意味着它无法获取我的位置,但我不明白为什么不这样做,因为有时它工作正常,长时间没有崩溃,然后如果我退出Activity然后尝试重新访问它应用程序通常会崩溃。

为什么会这样?

我是否应该尝试LatLng使用该方法保存值以解决此问题onResume();?不知道为什么它会起作用,有时我的位置找不到...

if (SphericalUtil.computeDistanceBetween(new LatLng(eventLatitude, eventLongitude), myLatLng) < metersToMiles) { mPostList.add(post);}这是在方法中抛出空指针的行readEventsNearby();。我在getLocation();方法中得到了我的位置。

问题是myLatLng我得到的,如下所示。为什么它会起作用,然后当我退出 Fragment 并重新输入时,它会产生null pointer?

分段

public class EventsNearbyFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

    private RecyclerView mRecyclerView;
    private PostAdapter mPostAdapter;
    private List<Post> mPostList;

    private SwipeRefreshLayout mSwipeRefreshLayout;
    private ProgressBar mProgressBar2;

    private FusedLocationProviderClient mFusedLocationProviderClient;
    private double myLatitude, myLongitude;
    private LatLng myLatLng;

    private TextView mDistance, mNoEventsNearBy;
    private Dialog mDialog;
    private ProgressBar mProgressBar;
    private Button mApply;
    private int miles;
    double metersToMiles;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext());
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            getMyLocation();
        } else {
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 44);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_events_nearby, container, false);

        mProgressBar2 = view.findViewById(R.id.progress_bar);
        ImageView backArrow = view.findViewById(R.id.back);
        ImageView filterIcon = view.findViewById(R.id.distance_filter);
        mNoEventsNearBy = view.findViewById(R.id.no_events_nearby);

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext());
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            getMyLocation();
        } else {
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 44);
        }

        filterIcon.setOnClickListener(v -> buildDialog());
        backArrow.setOnClickListener(v -> getActivity().getSupportFragmentManager().popBackStack());

        initializeRecyclerView(view);
        setSwipeRefreshLayout(view);

        return view;
    }

    private void buildDialog() {
        mDialog = new Dialog(getContext());
        mDialog.setContentView(R.layout.seek_bar);
        mDistance = mDialog.findViewById(R.id.text_view);
        mProgressBar = mDialog.findViewById(R.id.progress_bar);
        SeekBar seekBar = mDialog.findViewById(R.id.seek_bar);
        mApply = mDialog.findViewById(R.id.apply);
        setCancel();

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mProgressBar.setProgress(progress);
                mDistance.setText("" + progress + "");

                mApply.setOnClickListener(v -> {
                    SharedPreferences.Editor editor = getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE).edit();
                    editor.putInt("miles", progress);
                    editor.apply();
                    mDialog.dismiss();
                    readEventsNearby();
                });
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        mDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mDialog.show();
    }

    private void setCancel() {
        Button cancel = mDialog.findViewById(R.id.cancel);
        cancel.setOnClickListener(v -> mDialog.dismiss());
    }

    private void setSwipeRefreshLayout(View view) {
        mSwipeRefreshLayout = view.findViewById(R.id.refresh);
        mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.post(() -> {
            mSwipeRefreshLayout.setRefreshing(true);
            readEventsNearby();
        });
    }

    private void initializeRecyclerView(View view) {
        mRecyclerView = view.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setReverseLayout(true);
        linearLayoutManager.setStackFromEnd(true);
        mRecyclerView.setLayoutManager(linearLayoutManager);

        mPostList = new ArrayList<>();
        mPostAdapter = new PostAdapter(getContext(), mPostList);
        mRecyclerView.setAdapter(mPostAdapter);

        if (mRecyclerView.getAdapter().getItemCount() == 0) {
            mProgressBar2.setVisibility(View.VISIBLE);
        } else {
            mProgressBar2.setVisibility(View.GONE);
        }
    }

    private void getMyLocation() {
        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        Task<Location> task = mFusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(location -> {
            if (location != null) {
                myLatitude = location.getLatitude();
                myLongitude = location.getLongitude();

                // My location

                myLatLng = new LatLng(myLatitude, myLongitude);
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    private void readEventsNearby() {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                mPostList.clear();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    Post post = dataSnapshot.getValue(Post.class);
                    if (post != null && post.getLocation() != null) {
                        double eventLatitude = post.getLocation().getLatitude();
                        double eventLongitude = post.getLocation().getLongitude();

                        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("prefs", Context.MODE_PRIVATE);
                        miles = sharedPreferences.getInt("miles", 10);
                        metersToMiles = miles * 1609.344;

                        if (SphericalUtil.computeDistanceBetween(new LatLng(eventLatitude, eventLongitude), myLatLng) < metersToMiles) {
                            mPostList.add(post);
                        }
                    }
                }

                if (mPostList.size() == 0) {
                    mProgressBar2.setVisibility(View.GONE);
                    mNoEventsNearBy.setVisibility(View.VISIBLE);
                } else {
                    mProgressBar2.setVisibility(View.GONE);
                    mNoEventsNearBy.setVisibility(View.GONE);
                }

                mPostAdapter = new PostAdapter(getContext(), mPostList);
                mRecyclerView.setAdapter(mPostAdapter);
                mPostAdapter.notifyDataSetChanged();
                mSwipeRefreshLayout.setRefreshing(false);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                mSwipeRefreshLayout.setRefreshing(false);

            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 44) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getMyLocation();
            }
        }
    }

    @Override
    public void onRefresh() {
        readEventsNearby();
    }
}

标签: javaandroid

解决方案


它崩溃了,因为myLatLng变量null在执行时SphericalUtil.computeDistanceBetween(new LatLng(eventLatitude, eventLongitude), myLatLng)

这可能是由于以下一些可能性而发生的:

  1. 您添加了一个成功侦听器mFusedLocationProviderClient.getLastLocation(),但它可能不会成功,因此myLatLng永远不会被分配,而是null.
  2. 它可能会成功,但由于某种原因您在SphericalUtil.computeDistanceBetween(new LatLng(eventLatitude, eventLongitude), myLatLng)此之前执行,因此myLatLng仍然是null.

myLatLng我建议你在执行之前检查它的可空性SphericalUtil.computeDistanceBetween(new LatLng(eventLatitude, eventLongitude), myLatLng)并根据它做出反应。


推荐阅读