Iām trying to find out why the Google Play service crashes with a nullpointerexception error after the application returns from a background state such as device hibernation or to switch another program. Sometimes Google Play services pop up when the application starts. Therefore, I suppose that the problem lies somewhere on the way to the service, since there flows with rxjava there.
Note: I Inject GoogleApiClient in both MainActivity (field injection) and in GoogleApiService (constructor injection).
GoogleApiClient is introduced as @Singleton. I tried to trace why this happens for several hours without progress, any help was appreciated.
The application continues to work without any problems, the "Google Play Apps pop-up" is annoying, but . I see that one call to getuserLocAndWeather () returns a lost connection to Google Play services, but it immediately returns a valid result on the next call.
The actual link to the object in MainActivity and GoogleApiService is never null, the link is always the same as com.google.android.gms.internal.zzqd@a768e13 and is always connected when called.
Trace:
FATAL EXCEPTION: lowpool[3] Process: com.google.android.gms.persistent, PID: 12828 java.lang.NullPointerException: GoogleApiClient must not be null at ilk.a(:com.google.android.gms:73) at hys.<init>(:com.google.android.gms:115) at pof.<init>(:com.google.android.gms:86) at ppz.<init>(:com.google.android.gms:35) at ppx.<init>(:com.google.android.gms:179) at ppp.a(:com.google.android.gms:179) at buc.a(:com.google.android.gms:381) at jfo.run(:com.google.android.gms:1087) at itt.run(:com.google.android.gms:453) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at iyg.run(:com.google.android.gms:17) at java.lang.Thread.run(Thread.java:818)
My class of service: printout in try {} for the client always: true, regardless of whether the google play services failed or not.
Client: com.google.android.gms.internal.zzqd@3c738f4e Connected ?: True
public class GoogleApiService implements IGoogleApi{ private GoogleApiClient client; private static final String TAG = "GoogleApiClient"; @Inject public GoogleApiService(GoogleApiClient client){ this.client = client; } public Observable<UserCurrentInfo> getLocationWeather(){ Observable<WeatherResult> weatherObservable = Observable.create(subscriber -> { try { Log.d(TAG,"Trying to get some Weather"); Log.d(TAG,"Client: " + client.toString() + " Connected? :" + client.isConnected()); Awareness.SnapshotApi.getWeather(client) .setResultCallback(weather -> { if (!weather.getStatus().isSuccess()) { subscriber.onError(new Throwable("could not get weather")); Log.d(TAG," Error getting weather" + weather.getStatus().toString()); } else { Log.d(TAG,"Getting dem weathers"); subscriber.onNext(weather); subscriber.onCompleted(); } }); }catch (SecurityException e){ throw new SecurityException("No permission: " + e); } }); Observable<LocationResult> locationObservable = Observable.create(subscriber -> { try { Awareness.SnapshotApi.getLocation(client) .setResultCallback(retrievedLocation -> { if (!retrievedLocation.getStatus().isSuccess()) { subscriber.onError(new Throwable("Could not get location.")); Log.d(TAG," Error getting location"); } else { subscriber.onNext(retrievedLocation); subscriber.onCompleted(); } }); }catch (SecurityException e){ throw new SecurityException("No permission: " + e); } }); return Observable.zip(weatherObservable, locationObservable, (weather, location) -> { return new UserCurrentInfo(weather.getWeather(),location.getLocation()); }); }
Leading:
public class FavouritesPresenter implements BasePresenter<IFavouriteView>{ private IFavouriteView favView; private String TAG = "FavPresenter"; private Subscription subscription; private GetUserLocationWeatherUseCase useCase; @Inject FavouritesPresenter(GetUserLocationWeatherUseCase wlUseCase){ this.useCase = wlUseCase; } @Override public void onCreate() { } @Override public void onStop(){ if(subscription != null){ subscription.unsubscribe(); } } public void getUserLocAndWeather(){ subscription = useCase.execute().subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(info -> { favView.showText( formatStringDecimals(info.getWeather().getTemperature(Weather.CELSIUS)+"",2), info.getWeather().getConditions()[0], formatStringDecimals(""+info.getLocation().getLatitude(),3), formatStringDecimals("" + info.getLocation().getLongitude(),3) );}, err ->{favView.showText("??",0,"","");} ); }
USECASE:
public class GetUserLocationWeatherUseCase implements Usecase<UserCurrentInfo> { IGoogleApi apihelper; public GetUserLocationWeatherUseCase(IGoogleApi helper){ this.apihelper = helper; } @Override public Observable<UserCurrentInfo> execute(){ return apihelper.getLocationWeather(); }
Usage in mainactivity:
@Inject FavouritesPresenter favouritesPresenter; GoogleApiClient.ConnectionCallbacks connectionCallbacks; GoogleApiClient.OnConnectionFailedListener connectionFailedListener; @Inject GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); initInjector(); favouritesPresenter.attachView(this); favouritesPresenter.onCreate(); registerReceiverGPS(); } @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null){ registerCallbacks(this.mGoogleApiClient); registerFailedToConnect(this.mGoogleApiClient); mGoogleApiClient.connect(); } } @Override protected void onStop() { favouritesPresenter.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.unregisterConnectionCallbacks(this.connectionCallbacks); mGoogleApiClient.unregisterConnectionFailedListener(this.connectionFailedListener); mGoogleApiClient.disconnect(); } } @Override public void registerCallbacks(GoogleApiClient client){ this.connectionCallbacks = new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(@Nullable Bundle bundle) favouritesPresenter.getUserLocAndWeather();