0

I have a service in which I have a AsyncTask

if (s != null) {
                    if (!MainActivity.photoListSend.isEmpty()) {
                        if (MainActivity.photoListSend.size() > 0) {
                            File file = MainActivity.photoListSend.get(0);
                            if (file.exists())
                                file.delete();
                            MainActivity.photoListSend.remove(0);
                            Gson gson = new Gson();
                            String jsonCurProduct = gson.toJson(MainActivity.photoListSend);
                            SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("TAG", Context.MODE_PRIVATE);
                            SharedPreferences.Editor editor = sharedPref.edit();
                            editor.putString("TAG", jsonCurProduct);
                            editor.apply();
                            File imagesFolder = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                            assert imagesFolder != null;
                        }
                    }

                }

On this line :

String jsonCurProduct = gson.toJson(MainActivity.photoListSend);

I have java.util.ConcurrentModificationException

And this is my all class :

ublic class Sendrer extends Service {

    public static boolean running = false;
    private Timer timer = new Timer();
    private SendPhotoTask asyncSender;
    private Context context;
    private SharedPreferences sp;
    private SharedPreferences.Editor editor;

    public static String convertStreamToString(java.io.InputStream is) {
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
        sp = getSharedPreferences("pfref", Activity.MODE_PRIVATE);
        editor = sp.edit();
        Gson gson = new Gson();
        List<File> productFromShared = new ArrayList<>();
        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("TAG", Context.MODE_PRIVATE);
        String jsonPreferences = sharedPref.getString("TAG", "");

        Type type = new TypeToken<List<File>>() {
        }.getType();
        productFromShared = gson.fromJson(jsonPreferences, type);
        MainActivity.photoListSend = null;
        MainActivity.photoListSend = new ArrayList<>();
        if (productFromShared != null)
            MainActivity.photoListSend.addAll(productFromShared);
        Log.e("tworzenie serwisu ", "tworzenie");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("Dziełanie serwisu ", "Dziełanie");

        if (!running) {
            running = true;
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    asyncSender = new SendPhotoTask();
                    asyncSender.execute();
                }
            }, 1000 * 60 * 2);
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        if (running) {
            timer.cancel();
            asyncSender = new SendPhotoTask();
            asyncSender.cancel(true);
            running = false;
        }
        Log.e("service ", "nie działa");
        super.onDestroy();
    }

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

    public boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    class SendPhotoTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {
            running = true;
            if (MainActivity.photoListSend != null) {
                if (!MainActivity.photoListSend.isEmpty())
                    if (NetworkUtil.isNetworkAvailable(context)) {
                        if (MainActivity.photoListSend.size() > 0) {
                            MainActivity.isSend = true;
                            running = true;
                            InputStream responseInputStream = null;
                            Log.e("start wysłania ", "start");
                            try {
                                if (MainActivity.photoListSend.get(0).isFile()) {
                                    responseInputStream = HttpConnectionsUtil.sendPhotoRequest(getApplicationContext(), true, MainActivity.photoListSend.get(0).getName());
                                    if (responseInputStream != null) {
                                        String input = convertStreamToString(responseInputStream);
                                        if (input.equals("empty"))
                                            return "BAD";
                                        else {
                                            try {
                                                int tt = ResponseParser.getType(input);
                                                Log.e("TaG", tt + " ");

                                                if (tt == 0) {
                                                    return null;
                                                } else if (tt == -1) {
                                                    return null;
                                                }
                                            } catch (UnknownAnswerName e) {
                                                e.printStackTrace();
                                                return null;
                                            }
                                        }
                                    }

                                } else {
                                    return "BAD";
                                }

                            } catch (IOException e) {
                                e.printStackTrace();
                                return null;
                            }
//                    Log.e("Wysyłanie zdjęcia ", convertStreamToString(responseInputStream));
                            if (responseInputStream != null)
                                return convertStreamToString(responseInputStream);
                        }
                    }
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (NetworkUtil.isNetworkAvailable(context)) {
                if (sp.getBoolean("workOffLine", false)) {
                    editor.putBoolean("workOffLine", false);
                    editor.commit();
                    isConnect.setVisibility(View.VISIBLE);
                    imgIsSend.setVisibility(View.VISIBLE);
                    imgIsNet.setVisibility(View.GONE);
                }
            }
            if (s != null) {
                if (!MainActivity.photoListSend.isEmpty()) {
                    if (MainActivity.photoListSend.size() > 0) {
                        File file = MainActivity.photoListSend.get(0);
                        if (file.exists())
                            file.delete();
                        MainActivity.photoListSend.remove(0);
                        Gson gson = new Gson();
                        String jsonCurProduct = gson.toJson(MainActivity.photoListSend);
                        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("TAG", Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sharedPref.edit();
                        editor.putString("TAG", jsonCurProduct);
                        editor.apply();
                        File imagesFolder = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                        assert imagesFolder != null;
                    }
                }

            }
            if (s == null) {
                MainActivity.isSend = false;
            }
            if (!MainActivity.photoListSend.isEmpty()) {
                if (NetworkUtil.isNetworkAvailable(context)) {
                    if (MainActivity.photoListSend.size() > 0) {
                        asyncSender = new SendPhotoTask();
                        asyncSender.execute();
                        Log.e("Wysyłanie kolejnego ", "zdjecia");
                    } else {
                        context.stopService(new Intent(context, Sendrer.class));
                        asyncSender.cancel(true);
                        context.startService(new Intent(context, Sendrer.class));
                    }

                } else {
                    context.stopService(new Intent(context, Sendrer.class));
                    asyncSender.cancel(true);
                    context.startService(new Intent(context, Sendrer.class));
                }
            } else {
                MainActivity.isSend = false;
                context.stopService(new Intent(context, Sendrer.class));
                asyncSender.cancel(true);
                context.startService(new Intent(context, Sendrer.class));
            }
            running = false;
        }
    }
}
Krzysztof Pokrywka
  • 1,356
  • 4
  • 27
  • 50
  • 1
    please add full async task code. – Pratik Popat Jul 26 '17 at 09:14
  • just an opinion - I think using retrofit and an intent service is a much nicer way to handle this than a service and an async task, but you may well have your reasons. Why not have a db table/content provider and an intent service? Periodically check your db table for not uploaded entries using a timer or handler or task scheduler, then if some entries are there, fire some intent service calls to upload each image and mark each as complete/remove from not uploaded table in the callback if successful – Saik Caskey Jul 26 '17 at 09:31
  • You can fix this in two ways. Either handle the concurrencies and use a lock (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html) object for synchronization. Or you can use any iterable from the java concurrency package. Like the ConcurrentSkipListSet. (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html) – Debanjan Jul 26 '17 at 09:35

1 Answers1

2

That's because another thread is modifying MainActivity meanwhile. You can branch the line with

synchronized(MainActivity.this) {
    String jsonCurProduct = gson.toJson(MainActivity.photoListSend);
}

however you should be aware of possible performance issues because now all threads will be waiting till toJson method ends

Read more about the exception and how to avoid this

m.antkowicz
  • 13,268
  • 18
  • 37
  • Ok dzięki A jak sprawdzić czy serwis jest urucxhomiony tylok raz ? albo jak go uruchamić ? – Krzysztof Pokrywka Jul 26 '17 at 09:23
  • Bo z tego co widzę to serwis mi sie uruchamia parę razy – Krzysztof Pokrywka Jul 26 '17 at 09:25
  • 1
    @Krzysztof please use english - I know that it may seems to be weird to not talk in our native language but remember that if someone not understanding Polish will have same problem as you then comment will be useless for him :) due to your questions take a look at https://stackoverflow.com/questions/8019899/what-happens-if-a-service-is-started-multiple-times – m.antkowicz Jul 26 '17 at 09:33
  • Ok But could you explain me how I can start only one time a service ? – Krzysztof Pokrywka Jul 26 '17 at 09:40