2013-08-30 28 views
6

Sunucuyla bağlantı kurmak için service'u başlatmaya ve socket'u açmaya çalışıyorum.Ana iş parçacığı üzerinde hizmet nasıl çalıştırılır?

Düğme tıklandığında, yeni Thread oluştur ve sonra hizmeti başlat.

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

Sonra service, ben socket açıp sunucusu ile bağlantısı var deneyin

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

Ama bunu çağırdığınızda, ben hata

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* 

Sorunun düşünüyorum service'un main thread numaralı telefonunda olduğunu, ancak yeni (bağımsız) t üzerinde hizmete nasıl başlamalıyım? connection alive tutmak için devam ediyor?

+0

Sunucuyla bağlantıyı canlı tutmam gerekiyor. AsyncTask sadece bağlantıyı açar, bazı istekleri gönderir, bazı yanıtlar alır ve kapanır, bu yüzden servisle bunu – Ragaisis

+0

http://developer.android.com/guide/components/services.html uygulayabilirim. Konuyu genişletme hizmet sınıfı – Raghunandan

cevap

9

Bunun için IntentService'i kullanabilirsiniz. Sadece ana iş parçacığı bir Niyet ile normal olarak başlatın. Arka plan iş parçacığında onHandleIntent() yöntemi çalıştırılır. Soket kodunu buraya koy. İşte bir örnek kod.

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

} 

Etkinliğinizde, hizmeti aşağıdaki gibi başlatırsınız. Eğer uzun süreli hizmeti gerekirse

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

, normal bir hizmet oluşturmak ve orada bir iş parçacığı başlayabilir. İşte bir örnek. "Önplan" hizmeti olarak başladığınızdan emin olun. Bu, Android tarafından öldürmeden hizmetin daha uzun süre çalışmasına izin verecektir.

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

altında denetleyin Ama ben IntentService yalnızca bir kez görev olduğunu okudum. Bağlantıyı yuvadan canlı tutmalı, sunucuya istek göndermeli, yanıtı almalı ve sunucu komutlarını dinlemeliyim. Bu oldukça zor uzun vadeli bir görevdir. Bunu uygulamak için IntentService kullanabilir miyim? – Ragaisis

+3

@Ragaisis Normal servisi bir iş parçacığı ile daha iyi kullanmalısınız. Cevabımı güncelledim. Bu yardımcı olur mu? –

+0

Bu cevaba tamamen katılıyorum, ancak hizmette kullanmak yerine doğrudan bir iş parçacığı kullanmaya devam edemeyeceğimiz bir sorum var. Demek istediğim, onu farklı kılan şey. – Bhagyashri

3

Taşı ipliùinizle bu kodu:

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

Sadece bir örnek (Ben bu göreve uygun emin değilim) olarak:

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

Bilmen gerekir UI iş parçacığı üzerinde bir hizmet çalışıyor, bu nedenle bu hatayı aldınız. Android'deki çeşitli iş parçacığı yaklaşımları hakkında daha fazla bilgi için this nice site'u kontrol edin.

İlgili konular