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;
        }
    }
}
3
  • 1
    please add full async task code. Commented Jul 26, 2017 at 9: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 Commented Jul 26, 2017 at 9:31
  • You can fix this in two ways. Either handle the concurrencies and use a lock (docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/…) object for synchronization. Or you can use any iterable from the java concurrency package. Like the ConcurrentSkipListSet. (docs.oracle.com/javase/7/docs/api/java/util/concurrent/…) Commented Jul 26, 2017 at 9:35

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

4 Comments

Ok dzięki A jak sprawdzić czy serwis jest urucxhomiony tylok raz ? albo jak go uruchamić ?
Bo z tego co widzę to serwis mi sie uruchamia parę razy
@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 stackoverflow.com/questions/8019899/…
Ok But could you explain me how I can start only one time a service ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.