2013-08-30 17 views
6

我试图启动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 [email protected] with Intent { cmp=com.example.testofconnection/.ConnectonService (has extras) }: android.os.NetworkOnMainThreadException* 

我认为问题是servicemain thread,但我无法找到我应该如何开始新的服务(独立)吨保持connection alive

+0

我需要与活着的服务器保持连接。 AsyncTask只会打开连接,发送一些请求,得到一些响应并关闭,所以我发现使用服务我可以实现它 – Ragaisis

+0

http://developer.android.com/guide/components/services.html。检查扩展服务类 – Raghunandan

回答

9

您可以为此使用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; 
    } 

} 

在您的活动中,您启动服务如下。

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

如果您需要持久的服务,您可以创建一个正常的服务并在那里启动一个线程。这是一个例子。确保您将其作为“前台”服务启动。这将允许服务运行更长时间,而不会被Android杀死。

public class MyAsyncService extends Service { 

    private Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      while(true) { 
       // 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); 
    } 
} 
+2

下的主题但我读IntentService只是一次性任务。我应该通过套接字保持连接活动,向服务器发送一些请求,收到响应并收听服务器命令。这是相当困难的长期任务。我可以使用IntentService来实现它吗? – Ragaisis

+3

@Ragaisis你应该更好地使用线程的正常服务。我更新了我的答案。这有帮助吗? –

+0

我完全同意这个答案,但我有一个问题,我们不能继续直接使用线程而不是在服务中使用它?我的意思是让它与众不同。 – Bhagyashri

3

移动这个代码到你的主题:

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

只是作为一个例子(我不知道它这符合你的任务):

Thread t = new Thread(){ 
     public void run(){ 
      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(); 
      } 

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

你应该知道,一个服务正在UI线程上运行,所以你得到了这个错误。有关Android中各种线程方法的更多信息,请查询this nice site

相关问题