How to start a service not in the main thread?

I try to start service , and then open socket to connect to the server.

When I click the button, I create a new Thread and then start the service.

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

Then on service I try to open socket and have a connection to the server

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

But when I call it, I have a mistake

 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* 

I think the problem is that service is on the main thread , but I can’t find how I can start working with a new (independent) thread to keep the connection alive ?

+6
source share
2 answers

You can use IntentService for this. Just run it with Intent from the main thread. onHandleIntent() method executes in the background thread. Put the socket code here. Here is a sample code.

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

In your activity, you start the service as follows.

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

If you need a long-term service, you can create a regular service and start the stream there. Here is an example. Make sure you run it as a β€œforeground” service. This will allow the service to work longer without being killed by 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); } } 
+9
source

Move this code to your stream:

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

As an example (I'm not sure if this matches your task):

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

You should know that the service is running in the user interface thread, so you got this error. Check out this nice site for more information on the various approaches to streaming in Android.

+3
source

Source: https://habr.com/ru/post/952803/


All Articles