(Kotlin) Загрузка файла из внутренней памяти и использование его для рисования на холсте

У меня возникают проблемы с использованием текстового файла, сохраненного во внутренней памяти моего приложения, и его использованием для определения того, какие растровые изображения будут отображаться на холсте и каково будет их размещение. Файл успешно создается моим приложением. Кажется, есть проблема с «filesDir», но только при определенных обстоятельствах.

Проблема в том, что когда я вставляю

val file: List<String> = File(this.filesDir, "TempLayoutData.txt").readLines()

внутри «класса Canvas» или «переопределить удовольствие onDraw», «filesDir» внезапно становится «неразрешенной ссылкой».

Итак, чтобы обойти это, я создал класс "Макет". Это выглядит так:

class Layout : AppCompatActivity(){
    val file: List<String> = File(this.filesDir, "TempLayoutData.txt").readLines()
    val stagewidth = file[0].toInt() * 10
    val stagelength = file[1].toInt() * 10

    var layout = Array(stagelength) { IntArray(stagewidth) }

    var rowcounter = 0
    var columncounter = 0

    var read = File(this.filesDir, "TempLayout.txt").forEachLine {
        for (i in it) {
            layout[rowcounter][columncounter] = (i - 48).toInt()
            columncounter++
        }
        rowcounter++
        columncounter = 0
    }
}

Я протестировал его внутри «override fun onCreate» моего класса ViewLayout (который также содержит класс Canvas), и он работал как шарм.

Когда он находится прямо внутри класса Canvas, воплощенного в жизнь с помощью

val layout = Layout()

он строится без ошибок, однако, когда я запускаю свое приложение на своем телефоне, возникает следующая ошибка: «Попытка вызвать виртуальный метод« java.io.File android.content.Context.getFilesDir () »для нулевой ссылки на объект "

Как источник ошибки, он указывает прямо на

val file: List<String> = File(this.filesDir, "TempLayoutData.txt").readLines()

внутри моего класса Layout, когда его экземпляр создается внутри класса Canvas.

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


person Mati9319    schedule 10.02.2019    source источник
comment
Проблема в том, что вы никогда не должны вручную создавать экземпляры классов Activity - они являются важной частью платформы Android и будут работать неправильно, если они не запущены с намерением.   -  person Pawel    schedule 10.02.2019
comment
Спасибо. Дело в том, что если я стираю AppCompatActivity(), filesDir становится неразрешенной ссылкой, поэтому мой класс Layout должен быть действием, верно? Однако, если я собираюсь начать это с намерением, как именно я могу это сделать? Для меня важнее всего создать значение, которое является экземпляром класса Layout (поэтому я использую val layout = Layout()). Как я должен это сделать, используя намерение?   -  person Mati9319    schedule 11.02.2019
comment
filesDir — это метод Context, поэтому t должны расширить деятельность. Просто добавьте поле context в свой класс Layout (инициализированный в конструкторе) и используйте его, чтобы получить context.filesDir вместо this.   -  person Pawel    schedule 11.02.2019
comment
Большое спасибо @Pavel! Работает как часы! Мне также нужно было изменить val layout = Layout() на val layout = Layout(context), и теперь он работает безупречно!   -  person Mati9319    schedule 12.02.2019


Ответы (1)


Извините, что позаботился об этом так поздно, но я официально отвечаю на этот вопрос. Все благодаря помощи Павла!

Прежде всего, мой класс Layout никогда не должен быть классом активности. Я удалил расширение и добавил конструктор с Context. Я также изменил "this." на "context." перед "filesDir". Теперь это выглядит так:

class Layout (context: Context){
    private val file: List<String> = File(context.filesDir, "TempLayoutData.txt").readLines()
    val stageWidth = file[0].toInt() * 10
    val stageLength = file[1].toInt() * 10

    var layout = Array(stageLength) { IntArray(stageWidth) }

    private var rowCounter = 0
    private var columnCounter = 0

    var read = File(context.filesDir, "TempLayoutLayout.txt").forEachLine {
        for (i in it) {
            layout[rowCounter][columnCounter] = (i - 48).toInt()
            columnCounter++
        }
        rowCounter++
        columnCounter = 0
    }
}
person Mati9319    schedule 03.03.2019