如何不在主线程上运行服务? [英] How to run service not on main thread?

查看:84
本文介绍了如何不在主线程上运行服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试启动service,然后打开socket与服务器建立连接.

I'm trying to launch service and then open socket to have connection with server.

在按钮上,单击我创建新的Thread",然后启动服务.

On button click I create new Thread and then start service.

Thread t = new Thread(){
        public void run(){
            mIntent= new Intent(MainActivity.this, ConnectonService.class);
            mIntent.putExtra("KEY1", "Value used by the service");
            context.startService(mIntent);
        }
    };
t.start();

然后在service上,我尝试打开socket并与服务器建立连接

Then on service, I try to open socket and have connection with server

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //TODO do something useful


    try {
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
        socket = new Socket(serverAddr, SERVERPORT);
        Scanner scanner = new Scanner(socket.getInputStream());
        message = scanner.nextLine();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return Service.START_NOT_STICKY;
}

但是当我打电话时,我遇到了错误

But when I call it, I have error

08-30 08:56:49.268: E/AndroidRuntime(3751): java.lang.RuntimeException: Unable to start service com.example.testofconnection.ConnectonService@40ef02a8 with Intent { cmp=com.example.testofconnection/.ConnectonService (has extras) }: android.os.NetworkOnMainThreadException*

我认为问题是servicemain thread上,但是我找不到如何在新(独立)线程上启动服务以保持connection alive的原因?

I think problem is that service is on main thread, but I can't find how should I start service on new (independend) thread to keep connection alive?

推荐答案

您可以为此使用IntentService.只需在主线程中使用Intent正常启动它即可. onHandleIntent()方法在后台线程中执行.将您的套接字代码放在那里.这是示例代码.

You can use IntentService for this. Just launch it normally with an Intent from the main thread. onHandleIntent() method gets executed in background thread. Put your socket-code in there. Here is an example code.

public class MyIntentService extends IntentService {

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

    @Override
    protected void onHandleIntent(Intent intent) {
        // this method is called in background thread
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }    
}

在您的活动中,按以下方式启动服务.

In your activity you start the service as following.

startService(new Intent(this, MyIntentService.class));

如果需要长期服务,则可以创建普通服务并在其中启动线程.这是一个例子.确保将其作为前台"服务启动.这样可以使服务运行更长的时间,而不会被Android杀死.

If you need a long-lasting service, you can create a normal service and start a thread there. Here is an example. Make sure you launch it as "foreground" service. This will allow service to run longer without been killed by Android.

public class MyAsyncService extends Service {

    private AtomicBoolean working = new AtomicBoolean(true)

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while(working.get()) {
                // put your socket-code here
                ...
            }
        }
    }

    @Override
    public void onCreate() {

        // start new thread and you your work there
        new Thread(runnable).start();

        // prepare a notification for user and start service foreground
        Notification notification = ...
        // this will ensure your service won't be killed by Android
        startForeground(R.id.notification, notification);
    }

    @Override
    public onDestroy() {
        working.set(false)
    }
}

这篇关于如何不在主线程上运行服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆