1

I need to develop an app with a service that is able to get data from a server when the app is in background. I used a thread in order to run ThreadWorker() for long time when the app is background. (Previously I did a thread in my app: when the app was onStop() the thread stopped and that was not good for me. So I decided to go for a Service)

public class ServiceBG extends Service
{    
public class LocalBinder extends Binder {
    ServiceBG getService() {
        return ServiceBG.this;
    }
}


private final IBinder mBinder = new LocalBinder();

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return mBinder;
}

@Override
public void onCreate() {
    InitializeVariable();
}

private void InitializeVariable()
{
    this.mContext = this;
    this.working = false;
    this.canRun = true;
    this.serverCOM = new ServerCOM(myUrl,departmentID);
    ThreadWorker();
}

private void ThreadWorker()
{
    thread = new Thread(new Runnable() {
        @Override
        public void run() {
            int i=0 ;
            while (canRun)
            {                   
                try {
                    while (!serverCOM.hasActiveInternetConnection(mContext)) {
                        try {
                            Thread.sleep(4000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    list = serverCOM.GetFirmwareDeviceNameList();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                if(listDevice!=null) {
                    Log.d("serviceBG", String.valueOf(list.size()));

                    if (list.size() > 0) {


                        working = true;

                        Intent intent = new Intent();
                        intent.setAction(MY_ACTION);

                        intent.putExtra("DATAPASSED",list.get(0));

                        sendBroadcast(intent);
                        //complete action
                    }
                }

                try {
                    FirmwareUpdaterThread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    });
    thread.start();

}



@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //TODO do something useful
    return Service.START_STICKY;
}
}

My ServerCOM object is made like this:

 public class ServerCOM {
 public List<String> GetFirmwareDeviceNameList()
{
    AsyncGetNames asyncGetNames=new AsyncGetNames();
    asyncGetNames.execute(URL);
    try {
        this.NameList =asyncGetNames.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return this.NameList;
}

public boolean hasActiveInternetConnection(Context context) {
    if (isNetworkAvailable(context)) {
        try {
            HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
            urlc.setRequestProperty("User-Agent", "Test");
            urlc.setRequestProperty("Connection", "close");
            urlc.setConnectTimeout(1500);
            urlc.connect();
            return (urlc.getResponseCode() == 200);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error checking internet connection", e);
        }
    } else {
        Log.d(LOG_TAG, "No network available!");

    }
    return false;
}

private boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager  = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;
}


 private class AsyncGetNames extends AsyncTask<String, String, List<String>>
{
    public AsyncGetNames()
    {
    }
    @Override
    public List<String> doInBackground(String... params){
        List<String> list = null;
        try {
            URL url = new URL(params[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoInput(true);
            urlConnection.setRequestMethod("GET");
            urlConnection.setRequestProperty("Content-Type", "application/json");
            urlConnection.setRequestProperty("Accept", "*/*");
            InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
            //readStream(in);
            String resultString = Operations.convertStreamToString(inputStream);
            inputStream.close();

            String[] list1 = new Gson().fromJson(resultString, String[].class);
            list= Arrays.asList(list1);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}
 }

When I start this service I can get data from server. After more or less half an hour the service is not able to send requests anymore (I see this from Logcat in Android Studio). It seems that the request thread goes to sleep. Is there some possible interaction between this thread and AsyncTask request?

Daniele
  • 668
  • 2
  • 10
  • 25
  • Why aren't you using alarms instead of a worker thread loop? – Laur Ivan May 24 '16 at 09:18
  • I never used it. I will read the documentation. Thanks PS Is it a better approach? – Daniele May 24 '16 at 09:25
  • 2
    First of all, why you are using an async task inside of a thread? The request is already done in a background thread. It is not necessary to have the async task inside the background thread. Especially, considering that async task was designed to have a background process (doInBackground) and a method (onPostExecute) executed on the main thread. – Andrei T May 24 '16 at 11:57
  • Thanks for the suggestion. I'm working in moving the async task in the Thread. Maybe this is the way – Daniele May 24 '16 at 12:07
  • 1
    Instead of blocking a process, you let the system trigger your service (`IntentService`) from a `BroadcastReceiver`. The service would then take care of the actual business process and all you'd need to do is make sure requests don't overlap (skip processing if the service hasn't finished yet) like [described here](http://stackoverflow.com/questions/600207/how-to-check-if-a-service-is-running-on-android). – Laur Ivan May 24 '16 at 14:04

0 Answers0