当连接建立onConnectedToGooglePlayService()
时,我会创建与 google play服务建立连接的类。当新的mySerivce
启动时,首先要建立与播放服务的连接,如代码中所示。
问题是连接到播放服务需要一些时间,我无法确定在调用onStartCommand
时是否建立了连接,我无法从Intent获取信息。
所以我的问题是:处理这种情况的最佳方法是什么?我想在建立连接时创建一个全局变量和处理意图,但我不确定这是否是正确的方法。
public class myService extends Service implements ConnectedToGooglePlayService {
GoogleApiClient mGoogleApiClient;
@Override
public void onCreate() {
super.onCreate();
new ConnectToGooglePlayService(this, this).connect();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onConnectedToGooglePlayService(GoogleApiClient mGoogleApiClient) {
this.mGoogleApiClient = mGoogleApiClient;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
答案 0 :(得分:1)
由于Service
绑定是一个异步进程,暂停执行代码的最简单方法是阻止整个线程的执行,并在连接Service
后恢复它。
但是,在UI线程上调用onStartCommand()
并且阻止它不是一个好主意,因此您必须将工作卸载到后台线程。如果您不需要并行执行,那么IntentService
就足够了。但最常见的方法是这样的:
public class MyService extends Service implements ConnectedToGooglePlayService {
private final Object MONITOR = new Object();
GoogleApiClient mGoogleApiClient;
@Override
public void onCreate() {
super.onCreate();
new ConnectToGooglePlayService(this, this).connect();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// this block of code "pauses" the thread until mGoogleApiClient is not null
synchronized (MONITOR) {
while (mGoogleApiClient == null) {
try {
MONITOR.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// do some stuff that require google API client
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onConnectedToGooglePlayService(GoogleApiClient mGoogleApiClient) {
synchronized (MONITOR) {
this.mGoogleApiClient = mGoogleApiClient;
MONITOR.notifyAll();
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
我注意到的一件事是,您没有考虑远程Service
意外断开的可能性。我不知道您的可靠性要求是什么,但它可能会导致一些奇怪的错误。
我写了一篇关于绑定IPC服务的博客文章,可能对您有所帮助:How to establish a reliable (crash and kill tolerant) connection to bound IPC (e.g. AIDL) Service in Android
答案 1 :(得分:0)
您不需要在服务上@override onStartCommand也不需要使用GoogleApiClient作为全局变量,更好的方法是:
public class myService extends Service {
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
new ConnectToGooglePlayService(this, new ConnectToGooglePlayService(this, new ConnectedToGooglePlayService(){
@Override
public void onConnectedToGooglePlayService(GoogleApiClient mGoogleApiClient) {
// you can access the on start command parameters because you
// set the variables to be unchangeable by using the word final
}
}).connect();
return super.onStartCommand(final intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
答案 2 :(得分:-1)
看看它是否有效。
public class myService extends Service implements ConnectedToGooglePlayService {
GoogleApiClient mGoogleApiClient;
@Override
public void onCreate() {
super.onCreate();
new ConnectToGooglePlayService(this, this).connect();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
while(mGoogleApiClient == null || !mGoogleApiClient.isConnected()) {
Log.d("mGoogleApiClient status", "connecting...");
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onConnectedToGooglePlayService(GoogleApiClient mGoogleApiClient) {
this.mGoogleApiClient = mGoogleApiClient;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}