2011-02-28 21 views
25

我是新来的这个机器人。我正在使用一项服务来完成一些后台工作。所以我开始从我的活动服务如下。如何在Android的新线程启动服务

 getApplicationContext().bindService(
     new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class), 
     serviceConnection, 
     Context.BIND_AUTO_CREATE 
    ); 

但问题是android活动被阻止。直到服务,

  onServiceConnected(ComponentName className, IBinder service){ ..} 

被称为back.so我搜查了这一点。我开始知道我必须以新线程开始我的服务。所以请任何人帮助我这样做。

回答

34

要创建并启动一个新的线程,从活动里,你可以说:

Thread t = new Thread(){ 
public void run(){ 
getApplicationContext().bindService(
     new Intent(getApplicationContext(), MyAndroidUpnpServiceImpl.class), 
     serviceConnection, 
     Context.BIND_AUTO_CREATE 
    ); 
} 
}; 
t.start(); 

此外,通过缓存返回bindservice的价值,如果有的话,如果你需要它供以后使用。

+0

感谢Samuh我将检查了这一点... – bHaRaTh 2011-02-28 05:21:48

+1

喜Samuh其工作。现在它不会阻止我的活动,直到服务启动..非常感谢你的帮助......我还有一个问题。我将在下一个评论.. – bHaRaTh 2011-02-28 05:30:15

+0

一旦我们绑定服务从第一次活动,我们利用该服务,我们将解除它。所以假设在我的下一个活动中,如果我们想使用相同的服务,是否我们必须再次绑定它,或者在进程中是否存在错误。 – bHaRaTh 2011-02-28 05:34:23

1

如果有人在阅读本文时正在寻找一种解决方案,让UI线程保持流畅运行,那么最好检查一下AsyncTask任务here。 欢呼声。

+4

当您有代码运行而不启动应用程序时,AsyncTask将不会有用。 – Erol 2012-07-03 23:17:33

+0

我正在谈论保持UI线程免费,我没有看到你所说的连接...顺便说一句,服务是应用程序的一部分,它们都运行在同一个进程下。也许你的意思是在活动之外运行代码? – gor 2015-03-08 12:41:25

14

任何使用线程,Runnables,AsyncTask或其他服务的解决方案都会有常见问题

服务将阻止调用Activity直到服务启动。因此在某些情况下无法有效地对服务进行线程化。

解决方法是使用IntentService子类。如何实现

实施例:)

public class MyCustomService extends IntentService 
{ 
    private DatabaseAdapter mAdapter; 

    public MyCustomService() { 
     super("MyCustomService"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     super.onStartCommand(intent, flags, startId); 
     Toast.makeText(this, "MyCustomService Started", Toast.LENGTH_LONG).show(); 

     // Don't let this service restart automatically if it has been stopped by the OS. 
     return START_NOT_STICKY; 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) 
    { 
     Toast.makeText(this, "MyCustomService Handling Intent", Toast.LENGTH_LONG).show(); 
     // INSERT THE WORK TO BE DONE HERE 
    } 
} 

的onCreate(和的onDestroy也可以,只要重写为super.onWhatever()被称为在其内部。

+2

你不能用IntentService做所有的事情。服务有其自己的用法。 – Saty 2015-04-16 09:05:36

3

老问题,但我在回应,因为有人在另一个问题中提请我注意它。

OP的问题显然是由服务的onBind(...)花费很长时间并阻塞主线程造成的。正确的解决方案是不要那样做。该服务需要重新设计,以便onBind(...)快速返回。与Android API中的其他几乎一样,您应该始终在主线程中调用bindService(...)

原因是Java中的线程安全不仅仅是原子性的问题,而且也是visibility。 (向下滚动到可见性部分。)一般来说,除非另有明确说明,否则应始终假定每个Java API均为而非线程安全。

1

我会推荐使用IntentService,因为默认情况下IntentService在单独的线程上运行。但还是如果你的服务类扩展服务,然后使用此代码:

Thread thread = new Thread() { 
    @Override 
    public void run() { 
     startService(new Intent(getApplicationContext(), YourService.class)); 
    } 
}; 
thread.start(); 
相关问题