Исключение DeadObjectException при работе с Singleton — Android

#android #singleton

#Android #Синглтон

Вопрос:

Мое приложение — это приложение для рисования, которое позволяет пользователю рисовать на холсте, используя несколько разных цветов кисти. Приложение сохраняет изображения при нескольких запусках приложения, чтобы при загрузке программы пользователь мог переключаться между различными изображениями, используя кнопки «предыдущий» и «следующий». Мое приложение сохраняет рисунки как экземпляры моего пользовательского класса PaintingModel, который представляет одну картину, которая, в свою очередь, хранит список объектов Path .

 public class PaintingModel {
private List<Path> strokes;

public PaintingModel() {
    strokes = new ArrayList<>();
}

public void addStroke(Path stroke) {
    strokes.add(stroke);
}

public List<Path> getStrokes() {
    return strokes;
}
  

Способ, которым я сохраняю свои картины, — это коллекция объектов PaintingModel, то есть Список.

Синглтон, который я использую как способ доступа к глобальному состоянию приложения, содержит код, который сохраняет мой список картин и загружает их из файла сохранения при новых сеансах приложения. Я отладил сохранение и чтение из файла и уверен, что это работает правильно. Вот мой одноэлементный класс:

 public class Gallery {
private static Gallery gallery = null;
// context is required to access file writing/reading methods under Context class
private Context context = null;
// holds all saved paintings
private List<PaintingModel> paintings = new ArrayList<>();
// references the currently visible painting
private PaintingModel currentPainting; // represents the current currentPainting
// convert painting objects into serializable form
private Gson serializer = new Gson();
// references the object in memory that represents the saved painting information
private File saveFile;
// index of current painting
public int paintingIndex;
// name of saved painting file
private final String FILENAME = "gallery_save_file";
// currently selected splotch color
private int currentColor = Color.BLACK;

private Gallery(Context _context) {
    context = _context;
    saveFile = new File(context.getFilesDir(), FILENAME);
    paintingIndex = 0;
    currentPainting = new PaintingModel();
    paintings = readPaintingsFromFile();
    paintings.add(currentPainting);
}

public static Gallery getInstance(Context _context) {
    if (gallery == null)
        gallery = new Gallery(_context);
    return gallery;
}

public void newStroke(Path stroke) {
    currentPainting.addStroke(stroke);
    savePainting();
}

private void savePainting() {
    FileOutputStream fos;
    try {
        fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
        Type listType = new TypeToken<List<PaintingModel>>() {}.getType();
        String serializedPaintings = serializer.toJson(paintings, listType);
        fos.write(serializedPaintings.getBytes());
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * Read from the saved file to load all user-saved paintings
 * @return List data containing saved paintings from previous sessions
 */
public List<PaintingModel> readPaintingsFromFile() {
    FileInputStream fis;
    byte[] obs = new byte[(int) saveFile.length()]; // add enough space for n newlines
    try {
        if (saveFile.exists()) {
            fis = context.openFileInput(FILENAME);
            int bytesRead = fis.read(obs);
            if (bytesRead <= 0)
                Log.i("TAG", "read 0 bytes from save file");
            fis.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.i("TAG", "file not found");
    }
    Type listType = new TypeToken<List<PaintingModel>>() {}.getType();
    String deserializedData = new String(obs);
    List<PaintingModel> results = serializer.fromJson(deserializedData, listType);
    return (results == null) ? new ArrayList<PaintingModel>() : results;
}

public boolean deleteSaveFile() {
    return saveFile.delete();
}

public List<PaintingModel> getPaintings() {
    return paintings;
}

public PaintingModel getPainting() {
    return currentPainting;
}

public int getColor() {
    return currentColor;
}

public void setCurrentColor(int color) {
    currentColor = color;
}
  

Идея заключается в том, что когда создается одноэлементная «Галерея», она загружает все ранее сохраненные рисунки в «Список рисунков» из файла сохранения, к которому позже обращаются, когда мне нужно перебирать рисунки в представлении холста рисования. В этом и заключается проблема — когда я пытаюсь перерисовать предыдущую или следующую картину, обратившись к ее списку объектов Path, приложение завершает работу, и моя консоль запуска выдает исключение DeadObjectException, указывающее, что хост-процесс удален.

В моем классе view, который показывает текущий рисованный холст и где я пытаюсь нарисовать следующие / предыдущие рисунки, у меня есть метод:

 public void showNextPainting() {
    drawCanvas.drawColor(Color.GRAY);
    List<PaintingModel> paintings = Gallery.getInstance(getContext()).getPaintings();
    PaintingModel nextPainting = paintings.get(Gallery.getInstance(getContext()).paintingIndex);
    drawCanvas.drawPath(new Path(nextPainting.getStrokes().get(0)), drawPaint);
    invalidate();
}
  

который я использую, чтобы сначала стереть холст, а затем получить следующую картину в моем списке картин, хранящихся в singleton. Здесь я просто беру первую картину в своем списке в качестве начального теста. Независимо от того, какой объект рисования, приложение всегда выходит из строя, когда я пытаюсь нарисовать один путь в экземпляре PaintingModel. Этот код отлично работает, когда я рисую недавно созданный объект Path с простой формой, прикрепленной как прямоугольник.

Полная трассировка стека

Трассировка стека 1

Трассировка стека pt 2

Трассировка стека pt 3

Комментарии:

1. можете ли вы также опубликовать трассировку стека?

2. Добавлен @ginomempin.