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

在按钮上,单击“我创建新的Thread”,然后启动服务。

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并与服务器建立连接
@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;
}

但是当我调用它时,我遇到了错误
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的方法?

最佳答案

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

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

在您的 Activity 中,按以下方式启动服务。
startService(new Intent(this, MyIntentService.class));

如果需要长期服务,则可以创建普通服务并在其中启动线程。这是一个例子。确保将其作为“前台”服务启动。这将使服务运行更长的时间,而不会被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)
    }
}

关于android - 如何不在主线程上运行服务?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18526131/

10-11 22:30
查看更多