2013-08-30 4 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에 있지만 새로운 (독립) t 서비스를 시작하는 방법을 찾을 수 없습니다 계속 밟으려고 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)); 

오래 지속되는 서비스가 필요한 경우 일반 서비스를 만들고 거기에서 스레드를 시작할 수 있습니다. 다음은 그 예입니다. "전경"서비스로 시작해야합니다. 이렇게하면 안드로이드에 의해 죽지 않고 서비스를 더 오래 실행할 수 있습니다.

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을 확인하십시오.

관련 문제