如何在android中的新线程中启动服务

时间:2011-02-28 04:43:01

标签: android

我是这个机器人的新手。我正在使用服务做一些后台工作。所以我从我的活动开始服务如下。

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

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

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

被叫回来。所以我搜索了这个。我开始知道我必须在新线程中开始我的服务。所以请任何人帮我这样做。

5 个答案:

答案 0 :(得分:38)

要从活动内部创建和启动新主题,您可以说:

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

另外,如果需要,可以缓存bindservice返回的值(如果有的话)以供以后使用。

答案 1 :(得分:14)

任何使用Threads,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
    }
}
只要在它们内部调用super.onWhatever(),也可以覆盖

onCreate()和onDestroy。

答案 2 :(得分:3)

老问题,但我回答是因为有人在另一个问题上引起了我的注意。

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

原因是Java中的线程安全不仅仅是原子性问题,而且还是visibility。 (向下滚动到可见性部分。)通常,您应该始终假设每个Java API都线程安全,除非另有明确说明。

答案 3 :(得分:1)

如果有人在阅读此文章时正在寻找一个涉及让UI线程保持流畅运行的解决方案,那么最好查看AsyncTask任务here。 欢呼声。

答案 4 :(得分:1)

我建议使用IntentService,因为默认情况下IntentService在单独的线程上运行。但是,如果您的服务类扩展了Service,那么请使用以下代码:

        Include<TestModel> includes
            = chain => chain
                .Include(i => i.Field1)
                .Include(i => i.Field2)
         ObjectExtensions.Copy(source, destination, includes);