The question about the use of services - there is a need to perform long downloads from the network in the background, regardless of whether the application is running or not. Actually in the application itself in real time to update information about current downloads. In fact - the usual download manager. How do I best use the service in this case - as Started Service or Bound Service? There may be several downloads of simultaneous ones; accordingly, there is a need to display information about them in the application (if it is running).

Bound service - as far as I understand it completes its work, if the last component is disconnected from it, you can manage it in the activity through the created interface. But this is the question - if the application process is destroyed, is it considered a “disconnected component” from the service? And yes, the service is performed in a separate process.

    2 answers 2

    How do I best use the service in this case - as Started Service or Bound Service?

    Your promise is incorrect. The only difference between the Started Service and the Bound Service is that in the case of the Bound Service you get a handler / pointer to a service with which you can do something (for example, monitor its execution or how to manage the execution). When disconnecting, the service continues its work until it receives a signal for self-destruction.

    You need IntentService - a version of the service that runs in a separate thread and therefore does not slow down the UI stream.

    To your misfortune, the IntentService when receiving multiple requests, executes them sequentially, that is, you cannot perform many tasks in parallel. To parallelize their execution (for example, several downloads at the same time), you need to follow the instructions in the documentation - create your own IntentService , in which parallel execution is allowed, that is, onStart() creates its thread and works quickly and does not delay the service thread.

    Fortunately, there is such a ParallelIntentService implementation.

      For long-running operations, use: AsyncTask Example of implementing the Post request, where we get the answer in data. Of course, this is not a downloader for me, but you can change it to fit your needs.

        private static class SendLoginData extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... urls) { try { String myURL = urls[0]; String request = urls[1]; byte[] data; InputStream is; try { URL url = new URL(myURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestProperty("Content-Length", "" + Integer.toString(request.getBytes().length)); OutputStream os = conn.getOutputStream(); data = request.getBytes("UTF-8"); os.write(data); conn.connect(); int responseCode= conn.getResponseCode(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (responseCode == 200) { is = conn.getInputStream(); byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { baos.write(buffer, 0, bytesRead); } data = baos.toByteArray(); return new String(data, "UTF-8"); } } catch (Exception ignored) {} } catch (Exception ignored) {} return null; } } 

      If you need to communicate with the user during operation, here is an approximate scheme:

       private class MyAsyncTask extends AsyncTask<String, Integer, Integer> { @Override protected void onProgressUpdate(Integer... progress) { // [... Обновите индикатор хода выполнения, уведомления или другой // элемент пользовательского интерфейса ...] } @Override protected void onPostExecute(Integer... result) { // [... Сообщите о результате через обновление пользовательского // интерфейса, диалоговое окно или уведомление ...] } @Override protected Integer doInBackground(String... parameter) { int myProgress = 0; // [... Выполните задачу в фоновом режиме, обновите переменную myProgress...] publishProgress(myProgress); // [... Продолжение выполнения фоновой задачи ...] // Верните значение, ранее переданное в метод onPostExecute return result; } }