Почему getcontext () null только в одном методе? - PullRequest
0 голосов
/ 05 июня 2018

Здравствуйте, я делаю картографическое приложение, которое находится внутри ящика в Android Studio, все шло хорошо, пока я не начал играть с фрагментами, так как я довольно новичок в Android, я действительно не знаю, что происходит, илив чем причина проблемы.

Я заменил основной макет на макет карты, сделав его своим "домашним" макетом.Затем я добавил фрагмент, в котором я могу изменить язык приложения под названием «Конфигурация», и я вызываю этот фрагмент, когда в меню ящика нажимается кнопка «Конфигурация».

Я заметил, что хотяФрагмент конфигурации заменяет макет карты. Некоторые методы определения местоположения из фрагмента карты все еще активны в фоновом режиме, я знаю это, потому что сообщение Toast отображается каждый раз, когда приложение проверяет разрешение или изменяет местоположение. Я делал это в качестве наглядного пособия, поэтому я знаю, как он работает..

Есть 2 сценария, когда мое приложение вылетает из-за одной и той же ошибки в одной и той же строке кода, и это один из тостов, которые я добавил в качестве помощи.Для меня это странно, потому что все остальные тосты работают нормально, так как сообщение отображается, но когда он попадает к этому конкретному тосту в методе onLocationChanged, отображается следующая ошибка:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
    at android.widget.Toast.<init>(Toast.java:114)
    at android.widget.Toast.makeText(Toast.java:277)
    at android.widget.Toast.makeText(Toast.java:267)
    at com.tesseract.psiclops.zerov2.mapFragment.onLocationChanged(mapFragment.java:172)
    at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
    at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8)
    at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Итак, 2 вещиЭто вызывает ошибку:

1.- Когда я нажимаю кнопку «назад», и в бэкстеке нет фрагмента (я полагаю), поэтому он скрывает (закрывает? сворачивает?) приложение, затем я снова открываю его...it вылетает.

2.- Когда я захожу во фрагмент конфигурации и меняю язык.Примечание: метод, который я использую для смены языка, перезапускает действие, поэтому отображается изменение языка.

Я подумал, что, поскольку я закрываю приложение, нажимая кнопку «Назад» или вызывая мой язык, есть смысл, чтоgetcontext () становится нулевым после этого, но почему другие тосты показывают сообщение и вылетают только в этой конкретной строке?или конкретный метод?и как я могу предотвратить это ??

ПРИМЕЧАНИЕ: Когда я закомментирую тост, все работает нормально, без сбоев или чего-либо еще: S, мне действительно нужно понять, что происходит, чтобы я мог предотвратить любые проблемы позже.

MapFragment:

    public class mapFragment extends Fragment implements OnMapReadyCallback, LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private  GoogleMap mMap;
private GoogleApiClient mApiClient;
private Context mContext;

private OnFragmentInteractionListener mListener;

public mapFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_map, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);


 // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
            .findFragmentById(R.id.map1);
    mapFragment.getMapAsync(this);

}

private void SetSancrisM(final GoogleMap mMap) {

    // Add a marker in Sancris and move the camera

   // LatLng sancris = new LatLng(16.736380, -92.638795);
    LatLngBounds SanCris = new LatLngBounds(new LatLng(16.720215, -92.684189), new LatLng(16.749950, -92.596649));


    //mMap.addMarker(new MarkerOptions().position(sancris).title("Marker in Sancris"));
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SanCris.getCenter(), 16));
    //mMap.setLatLngBoundsForCameraTarget(SanCris);


}



@Override
public void onMapReady(GoogleMap googleMap) {

    mMap = googleMap;
    mMap.getUiSettings().setZoomControlsEnabled(true);

    try {
        // Customise the styling of the base map using a JSON object defined
        // in a raw resource file.
        boolean success = googleMap.setMapStyle(
                MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.style_json));

        if (!success) {
            Toast.makeText(mContext, "Chido3", Toast.LENGTH_SHORT).show();
        }
    } catch (Resources.NotFoundException e) {
        Toast.makeText(mContext, "No cargó el styla", Toast.LENGTH_SHORT).show();
    }

    //Calls the function that moves the cam to Sancris
    SetSancrisM(mMap);


    //Location permission conditions

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        Toast.makeText(mContext, "Failed to get location permission", Toast.LENGTH_SHORT).show();
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        return;

    } else {

        if (!mMap.isMyLocationEnabled()) {
            mMap.setMyLocationEnabled(true);
            Toast.makeText(mContext, "Chido", Toast.LENGTH_SHORT).show();

        }

    }


    mApiClient = new GoogleApiClient.Builder(getContext())
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    mApiClient.connect();


}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 200: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(mContext, "Failed to get permission 2", Toast.LENGTH_SHORT).show();

                } else {
                    mMap.setMyLocationEnabled(true);
                    Toast.makeText(mContext, "Chido2", Toast.LENGTH_SHORT).show();

                }
            }
        }
    }
}



@Override
public void onLocationChanged(Location location) {
    if(location==null){
        Toast.makeText(mContext, "No Location 4", Toast.LENGTH_SHORT).show();
    }else{
        LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
        CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
        mMap.animateCamera(update);

        Toast.makeText(mContext, "Chido4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
        }

}

LocationRequest mLocReq;

@Override
public void onConnected(@Nullable Bundle bundle) {

    mLocReq = LocationRequest.create();
    mLocReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocReq.setInterval(1000);

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocReq, this);

    Toast.makeText(mContext, "Chido5", Toast.LENGTH_SHORT).show();

}







@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}







//Este código tiene que ver con la comunicación entre fragmentos y actividades, osea déjalo para después


// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}


@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
    mContext=context;
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}




/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}
}

Тост, который не работает внутри метода onLocationChanged

@Override
public void onLocationChanged(Location location) {
    if(location==null){
        Toast.makeText(getContext(), "No Location 4", Toast.LENGTH_SHORT).show();
    }else{
        LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
        CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
        mMap.animateCamera(update);

        Toast.makeText(getContext(), "Good4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
        }

}

Все остальные тосты внутри методов mapfragment работают нормально.

Если вам нужно больше кода, пожалуйста, спросите меня здесь, и я добавлю его для вас.Заранее большое спасибо !!

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

getContext() возвращает ненулевое значение только тогда, когда Фрагмент присоединен к его Содержащему Деятельности - между onAttach() и onDetach().Если у вас есть обратный вызов, который происходит вне этих событий, значит, вы не очищаете своих слушателей должным образом.

Самое раннее, что вы должны создать своего слушателя (т. Е. Вызов requestLocationUpdates()), это onAttach().

Затем необходимо отменить регистрацию слушателя (т. Е. Позвонить removeUpdates()) в onDetach(), чтобы предотвратить утечку LocationListener и всего фрагмента.

Как правило, вам следуетзапрашивать обновления только тогда, когда ваш фрагмент виден на экране.В этом случае вы должны зарегистрироваться в onStart() и отменить регистрацию в onStop().

0 голосов
/ 05 июня 2018

Объявите переменную контекста во фрагменте

private Context mContext;

Инициализируйте ее из onAttach ()

 @Override
 public void onAttach(Context context) {
 super.onAttach(context);
 mContext = context;

}

Ваш тост будет

  Toast.makeText(mContext,getString(R.string.toast) , Toast.LENGTH_LONG).show();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...