2016-12-29 19 views
-2

Я прочитал много других ответов по той же проблеме, но это другое.NullPointerException при получении фрагмента карты

Мое приложение содержит активность, которая показывает мое текущее местоположение на карте. Моя основная деятельность не та, которая показывает карту.

Вот код для этой деятельности (карта, показывающая активность):

public class ActivityShowsNearby extends BaseActivity implements GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     LocationListener, 
     OnMapReadyCallback { 

    private static final String TAG = "ActivityShowsNearby"; 
    private static GoogleApiClient mGoogleApiClient; 
    private Location mCurrentLocation; 
    private LocationRequest mLocationRequest; 


    private static final int LOCATION_REQUEST_INTERVAL = 1000 * 60; //60 seconds 
    private static final int LOCATION_REQUEST_FASTEST_INTERVAL = 1000 * 60; //60 seconds 


    // Request codes... 


    private GoogleMap mGoogleMap; 
    private static final int DEFAULT_ZOOM = 15; 
    private final LatLng mDefaultLocation = new LatLng(28.636424, 77.374493); 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     Log.v(TAG, "onCreate"); 
     super.onCreate(savedInstanceState); 
     super.setContentView(R.layout.activity_shows_nearby); 

     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 

    } 


    @Override 
    protected void onStart() { 
     Log.v(TAG, "onStart"); 

     mGoogleApiClient.connect(); 
     super.onStart(); 


    } 

    @Override 
    protected void onResume() { 
     Log.v(TAG, "onResume"); 

     if (mGoogleApiClient.isConnected()) { 
      Log.v(TAG, "Starting location updates..."); 

      startLocationUpdates(); 
     } 
     super.onResume(); 
    } 

    @Override 
    protected void onPause() { 
     Log.v(TAG, "onPause"); 
     if (mGoogleApiClient.isConnected()) { 
      Log.v(TAG, "Removing location updates..."); 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 
     super.onPause(); 
    } 


    @Override 
    protected void onStop() { 
     Log.v(TAG, "onStop"); 

     mGoogleApiClient.disconnect(); 
     super.onStop(); 
    } 


    @Override 
    public void onConnected(Bundle bundle) { 
     startLocationUpdates(); 
     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 

     if (mapFragment == null) { 
      Log.v(TAG, "mapFragment is null"); 
     } else { 
      Log.v(TAG, "mapFragment is NOT null"); 

     } 
     mapFragment.getMapAsync(this); 

    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.v(TAG, "mGoogleApiClient connection suspended"); 


    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.v(TAG, "mGoogleApiClient connection failed"); 


    } 

    private void createLocationRequest() { 
     if (mLocationRequest == null) { 
      mLocationRequest = new LocationRequest(); 
      mLocationRequest.setInterval(LOCATION_REQUEST_INTERVAL); 
      mLocationRequest.setFastestInterval(LOCATION_REQUEST_FASTEST_INTERVAL); 
      mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     } 

    } 

    private void startLocationUpdates() { 
     createLocationRequest(); 
     try { 
      LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, 
        mLocationRequest, 
        this 
      ); 
     } catch (SecurityException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     mCurrentLocation = location; 
     updateMap(); 
    } 



    //@SuppressWarnings("MissingPermission") 
    @Override 
    public void onMapReady(GoogleMap googleMap) { 


     Log.v(TAG, "onMapReady"); 
     mGoogleMap = googleMap; 

     updateLocationUI(); 

     if (mCurrentLocation != null) { 
      googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
        new LatLng(mCurrentLocation.getLatitude(), 
          mCurrentLocation.getLongitude()), DEFAULT_ZOOM)); 
     } else { 
      googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM)); 
     } 

    } 

    private void updateMap() { 
     if (mGoogleMap == null) { 
      return; 
     } 
     mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
       new LatLng(mCurrentLocation.getLatitude(), 
         mCurrentLocation.getLongitude()), DEFAULT_ZOOM)); 
    } 


    @SuppressWarnings("MissingPermission") 
    private void updateLocationUI() { 

     if (mGoogleMap == null) { 
      Log.v(TAG, "mGoogleMap is null"); 
      return; 
     } 

     mGoogleMap.setMyLocationEnabled(true); 
     mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true); 


    } 

} 

Очевидно, что эта деятельность простирается от BaseActivity.java, который я создал, чтобы показать панель навигации. Вот код BaseActivity.java

public class BaseActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{ 

    private static final String TAG = "BaseActivity"; 
    private Toolbar toolbar; 
    private DrawerLayout drawerLayout; 
    private ActionBarDrawerToggle actionBarDrawerToggle; 
    private NavigationView navigationView; 

    //These two values will be used in unison -- see their usage 
    private boolean mDrawerItemClicked; 
    private int mDrawerItemSelectedId; 


    public NavigationView getNavigationView() { 
     return navigationView; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.d(TAG, "onCreate"); 

     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public void setContentView(int layoutResID) { 
     Log.d(TAG, "setContentView"); 

     super.setContentView(layoutResID); 
     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
    } 

    //Other navigation drawer set up codes... 
} 

Когда приложение запускается первый раз, моя основная деятельность показывает вверх. Затем пользователь может открыть навигационный ящик и выбрать один из элементов навигационного ящика, чтобы открыть мою активность отображения карт i.e ActivityShowsNearby, как показано на рисунке ниже.

Here is the screenshot of the same.

В этом проблема.

От моего основного вида деятельности открываю ящик для навигации и выбираю show near me, чтобы открыть ActivityShowsNearby. Затем я снова вернусь, чтобы вернуться к основному действию. Все работает отлично до этого. Но теперь, если я открою навигационный ящик и снова выберите show near me, чтобы снова открыть операцию ActivityShowsNearby, тогда приложение CRASHES.

Вот LogCat три случаев:

задерживаясь SHOW NEAR ME первый раз.

12-29 16:30:53.696 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onCreate 
12-29 16:30:54.386 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onStart 
12-29 16:30:54.416 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onResume 
12-29 16:30:54.416 8585-8585/sumit.example.com.movie D/InputTransport: Input channel constructed: name='d9453f5 sumit.example.com.movie/com.example.sumit.movie.ActivityShowsNearby (client)', fd=56 
12-29 16:30:54.596 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: Connected to Google play services. 
12-29 16:30:54.636 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: mapFragment is NOT null 
12-29 16:30:54.786 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onMapReady 

После того как я нажимаю назад от моего ActivityShowsNearby:

12-29 16:31:02.576 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onPause 
12-29 16:31:02.576 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: Removing location updates... 
12-29 16:31:02.986 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onStop 
12-29 16:31:02.996 8585-8585/sumit.example.com.movie D/InputTransport: Input channel destroyed: name='d9453f5 sumit.example.com.movie/com.example.sumit.movie.ActivityShowsNearby (client)', fd=56 

Наконец, после того, как я открыть панель навигации снова нажмите show near me

12-29 16:31:07.856 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onCreate 
12-29 16:31:07.906 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onStart 
12-29 16:31:07.906 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: onResume 
12-29 16:31:07.906 8585-8585/sumit.example.com.movie D/InputTransport: Input channel constructed: name='d32ef5a sumit.example.com.movie/com.example.sumit.movie.ActivityShowsNearby (client)', fd=82 
12-29 16:31:08.016 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: Connected to Google play services. 
12-29 16:31:08.016 8585-8585/sumit.example.com.movie V/ActivityShowsNearby: mapFragment is null 
12-29 16:31:08.026 8585-8585/sumit.example.com.movie E/AndroidRuntime: FATAL EXCEPTION: main 
                     Process: sumit.example.com.movie, PID: 8585 
                     java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference 
                      at com.example.sumit.movie.ActivityShowsNearby.onConnected(ActivityShowsNearby.java:168) 
                      at com.google.android.gms.common.internal.zzm.zzq(Unknown Source) 
                      at com.google.android.gms.internal.zzaal.zzo(Unknown Source) 
                      at com.google.android.gms.internal.zzaaj.zzvE(Unknown Source) 
                      at com.google.android.gms.internal.zzaaj.onConnected(Unknown Source) 
                      at com.google.android.gms.internal.zzaan.onConnected(Unknown Source) 
                      at com.google.android.gms.internal.zzzy.onConnected(Unknown Source) 
                      at com.google.android.gms.common.internal.zzl$1.onConnected(Unknown Source) 
                      at com.google.android.gms.common.internal.zzf$zzj.zzwZ(Unknown Source) 
                      at com.google.android.gms.common.internal.zzf$zza.zzc(Unknown Source) 
                      at com.google.android.gms.common.internal.zzf$zza.zzu(Unknown Source) 
                      at com.google.android.gms.common.internal.zzf$zze.zzxa(Unknown Source) 
                      at com.google.android.gms.common.internal.zzf$zzd.handleMessage(Unknown Source) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:7406) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

Что здесь проблема?

Предположим, что я разрешил разрешение и настройки местоположения.

Вот мой activity_show_nearby.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    tools:openDrawer="start"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:fitsSystemWindows="true" 
     android:orientation="vertical" 
     tools:context="com.example.sumit.movie.MovieActivity"> 


     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      android:elevation="4dp" 
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 

     <!-- Start of replacement of fragment-container--> 


     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical" 
      android:id="@+id/activity_shows_nearby_location_layout"> 

      <fragment 
       android:id="@+id/map" 
       android:name="com.google.android.gms.maps.SupportMapFragment" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"/> 


     </LinearLayout> 

     <!--End of replacement of fragment container--> 


    </LinearLayout> 


    <android.support.design.widget.NavigationView 
     android:id="@+id/nav_view" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     android:fitsSystemWindows="true" 
     app:headerLayout="@layout/nav_header_movie" 
     app:menu="@menu/activity_movie_drawer" /> 

</android.support.v4.widget.DrawerLayout> 
+0

напишите 'activity_shows_nearby.xml' файл –

+0

Добавлено, пожалуйста Проверь сейчас. –

+0

Обеспечьте [mcve]. Это, по-видимому, простая проблема транзакции фрагмента, но здесь есть способ для многих бесполезных данных. – AxelH

ответ

-1

Добавить class атрибут вместо android:name

<fragment 
    android:id="@+id/map" 
    class="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

Проверьте для получения дополнительной информации MapFragment

+0

Все еще сбой .. –

+0

Очистить проект и повторите попытку. –

-1

Ваш журнал показывает, что объект фрагмент является пустым:

V/ActivityShowsNearby: mapFragment is null 

Итак, вы пытаетесь вызвать метод (getMapAsync) на нем, что вызывает ошибку.

Также убедитесь, что вы перекрывая все методы жизненного цикла (заметил OnDestroy отсутствует)

@Override 
public void onDestroy(){ 
    super.onDestroy(); 
} 
+2

Переопределение метода просто для вызова объявления суперкласса бесполезно. И я верю, что OP попросит понять, почему он NULL только после того, как он снова открыл активность, так как есть журнал, чтобы проверить, является ли он NULL;) – AxelH

0

Попробовал код, кроме инициализации меню

app:headerLayout="@layout/nav_header_movie" 
app:menu="@menu/activity_movie_drawer" 

Фрагмент не является нулевым (LOG запись: MapFragment НЕ null) Попробуйте очистить и перекомпилировать проект