2016-08-12 42 views
0

我有类创建连接到谷歌播放服务,当连接建立时onConnectedToGooglePlayService()被调用。当新的mySerivce开始时,首先要建立连接到播放服务,您可以在代码中看到。Android服务asyncrounous:如何确保连接建立之前运行onStartCommand

的问题是,连接到发挥服务需要一些时间,我不能肯定的是,当onStartCommand叫我不能得到意向信息建立连接。

所以我的问题是:处理这种情况的最佳方法是什么?连接建立后,我想创建一个全局变量和处理意图,但我不确定这是做到这一点的正确方法。

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

目前尚不清楚你想要达到的目标。在调用onConnectedToGooglePlayService之前,确保'onStartCommand'中的代码不会被执行? – Vasiliy

+0

是的,这就是我想要实现的目标 – user2610533

回答

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被意外中断的可能性。我不知道你的可靠性要求是什么,但它可能导致一些bizzare错误。

我写了一个博客帖子大约势必IPC服务,可能对您有所帮助:How to establish a reliable (crash and kill tolerant) connection to bound IPC (e.g. AIDL) Service in Android

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

} 
+0

这是一个很好的解决方案,但是当Activity被销毁时会发生什么? – user2610533

+0

你必须在你想开始这个服务的每个类上实现这个接口。由于每次都会启动构造函数,因此只应调用该类的googlePlayServiceConnected方法。 – fluffyBatman

+0

我注意到你试图通过调用yourService.start()来启动服务。但是这不起作用,因为服务是以Intent和callins开始的startService() – user2610533

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

} 
+0

我需要InStartCommand附带的Intent信息() – user2610533

+0

那么在这种情况下,只需修改代码即可(假设第二个参数是ConnectToGooglePlayService) –

+0

另外还有一件事,如果要将数据发送到您的活动,请不要链接它们与接口。当活动被破坏并且它变为空时,它会崩溃,使用广播接收器 - > http://www.tutorialspoint.com/android/android_broadcast_receivers.htm –

相关问题