2013-08-30 7 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 रखने के लिए hread?

+0

मुझे सर्वर के साथ कनेक्शन रखने की आवश्यकता है। AsyncTask केवल कनेक्शन खोलता है, कुछ अनुरोध भेजता है, कुछ प्रतिक्रिया प्राप्त करता है और बंद हो जाता है, इसलिए मैंने पाया कि सेवा के साथ मैं इसे – Ragaisis

+0

http://developer.android.com/guide/components/services.html लागू कर सकता हूं। सर्विस क्लास – Raghunandan

उत्तर

9

आप इसके लिए IntentService का उपयोग कर सकते हैं। इसे मुख्य थ्रेड से एक इरादे से सामान्य रूप से लॉन्च करें। 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

@ रैगैसिस आपको थ्रेड के साथ सामान्य सेवा का बेहतर उपयोग करना चाहिए। मैंने अपना जवाब अपडेट किया। क्या यह मदद करता है? –

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

आपको पता होना चाहिए कि यूआई थ्रेड पर एक सेवा चल रही है, इसलिए आपको यह त्रुटि मिली है। Android में विभिन्न थ्रेडिंग दृष्टिकोणों के बारे में अधिक जानकारी के लिए this nice site देखें।

संबंधित मुद्दे