android - GoogleApiClient 不得为 null [Awareness API]

标签 android dependency-injection rx-java google-api-client dagger-2

我试图找出为什么在应用程序从后台状态(例如设备 sleep 或切换其他程序)恢复后,Google Play 服务会崩溃并出现 nullpointerException。有时,Google Play 服务会在应用程序启动时弹出崩溃窗口。所以我假设问题出在服务路径上的某个地方,因为 rxjava 就在那里发生线程。

Note: I Inject GoogleApiClient in both MainActivity (field injection) and in GoogleApiService (constructor injection). 

GoogleApiClient 作为 @Singleton 注入(inject)。我一直试图追踪为什么会发生这种情况几个小时,但没有任何进展,感谢任何帮助。

应用程序继续工作,没有任何问题,但“Google Play 服务弹出窗口”很烦人,我看到对 getuserLocAndWeather() 的一次调用返回与 google play 服务丢失的连接,但它立即返回下一次调用的有效结果。

MainActivity 和 GoogleApiService 中的实际对象引用永远不会为 null,引用始终相同,例如 com.google.android.gms.internal.zzqd@a768e13,并且在调用时始终保持连接。

追踪:

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)

我的服务类:客户端的 try{} 中的打印始终为:true,无论 google play 服务是否崩溃。

客户端:com.google.android.gms.internal.zzqd@3c738f4e 已连接? :正确

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());
            });
}

演讲者:

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,"","");}
            );
}

用例:

public class GetUserLocationWeatherUseCase implements Usecase<UserCurrentInfo> {
IGoogleApi apihelper;

public GetUserLocationWeatherUseCase(IGoogleApi helper){
    this.apihelper  = helper;
}
@Override
public Observable<UserCurrentInfo> execute(){
    return apihelper.getLocationWeather();

}

主要 Activity 中的用法:

@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(); //Call to presenter that initiates the observable chain, actually this              comes later after some GPS checks and such, but for easier cohesion
        }
        @Override
        public void onConnectionSuspended(int i) {}
    };
    client.registerConnectionCallbacks(this.connectionCallbacks);
}

最佳答案

在 onStart() 方法中仅连接 googleApiClient 的对象,其余内容在 onCreate() 方法中实现。

关于android - GoogleApiClient 不得为 null [Awareness API],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38244651/

相关文章:

java - 使用 RxAndroid 进行链 2 次调用并重试

java - 当父类(super class)使用@Inject时,如何构造一个类?

android - 将textNoSuggestions添加到editText后如何在键盘上显示回车按钮?

android - 如何根据升序整数对sqlite表进行排序?

android - 按下后退按钮时如何用 fragment A替换 fragment C?

c# - 具有多个接口(interface)的 Autofac Open Generic Decorator 导致循环依赖解析

java - 在javaConfig中使用@Qualifier + @Bean(autowire=Autowire.BY_TYPE)

rx-java - 在简单情况下使用响应式(Reactive)编程的原因

java - Rxjava tolist() 没有完成

java - 如何为欧洲语言设置数字格式