Run Service with a BroadcastReceiver

1

I need to execute a Service through a BroadcastReceiver , but the error occurs: android.os.NetworkOnMainThreadException .

To "deviate" from the error, I'm using the code below, but I want to do it the right way.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

Do I need to create a IntentService for this, or are there other ways?

    
asked by anonymous 11.03.2018 / 00:09

2 answers

3

According to the documentation:

  

Attention: A service runs on the primary thread in your   hosting process - the service does not create its own thread and   is not executed in a separate process (unless specified). That   means that if the service is to perform any labor intensive   or blocking operations (such as MP3 or network playback), you   you must create a new thread inside the service. Using a   separate thread, you will reduce the risk of   Non-responding application (ANR) and the main   application can remain dedicated to user interaction with   activities.

In English:

  

Caution: A service runs in the main thread of its hosting process-the   service does not create its own thread and does not run in a separate   (unless you specify otherwise). This means that, if your   service is going to do any CPU intensive work or blocking operations   (such as MP3 playback or networking), you should create a new thread   within the service to do that work. By using a separate thread, you   will reduce the risk of Application Not Responding (ANR) errors and   the application's main thread can remain dedicated to user interaction   with your activities.

That is, you are trying to make a request on the main thread, so the exception occurs.

Placing the request on a separate thread should resolve your issue.

To request a separate thread there are several ways. The simplest is:

Thread thread = new Thread(new Runnable(){
  @Override
  public void run(){
    List<User> users = getUsersFromWebservice();
  }
});
thread.start();

You have AsyncTask, my favorite when I'm not using Retrofit.

class UserAsync extends AsyncTask<Void, Void, List<User>>{
    protected void onPreExecute (){
        super.onPreExecute();

        /*
        Aqui é a hora pra você fazer tudo antes da requisição começar
        Ex: Alterar visibilidade de algumas view, avisar usuário e etc.
        */
    }

    protected String doInBackground(Void...arg0) {
        //Aqui você faz a requisição.
        return getUsersFromWebservice();
    }

    protected void onPostExecute(List<User> users) {
        super.onPostExecute(users);
        //Aqui você tem acesso ao retorno da  doInBackground(Void...arg0)
    }
}

However, there is a lib called Retrofit . She, in addition to making the requisition, manages the entire threading process for you. It also has the Volley lib, but it does not do all request management with threads the same as Retrofit does, you'll have to do it using either of the two examples above.

    
11.03.2018 / 04:01
1

With the service running and already creating the note Thread :

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {

                // Aqui seu conteúdo para execução

            }
        };

        Thread t = new Thread(runnable);
        t.start();
        return Service.START_STICKY;

}
    
11.03.2018 / 15:01