Ошибка чтения файла внутренней памяти

213
06 ноября 2017, 20:11

Логика приложения: проверяю существование файла, если его нет - вызываю внутренний класс ParseBookCovers, который парсит json файл с сервера и записывает его в файл. Так вот: при первом запуске программы приложение вылетает с ошибкой Error in Reading: /data/user/0/ru.yandex.matu1.toddlersbook/files/booklist.json (No such file or directory) но файл при этом записывается в память. Второй запуск - все работает нормально. Это понятно, так как файл уже появляется в памяти. Если очистить память - снова ошибка. Пробовал дебагом пройти по программе - все работает как надо и ошибка не появляется. То есть логика приложения срабатывает как надо - если нет файла - он создается - затем из него идет чтение.

import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import com.thin.downloadmanager.DownloadRequest;
import com.thin.downloadmanager.ThinDownloadManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    private List<Cover> covers;
    private RecyclerView recyclerView;
    private String filename;
    private String fileUrl;
    private ArrayList<Uri> urisImg;
    private ArrayList<String> urls;
    private static final String LOG_TAG = "my_log";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        LinearLayoutManager llm = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(llm);
        recyclerView.setHasFixedSize(true);
        File file = new File(this.getCacheDir().getPath() + File.separator + "booklist.json");
        if (!file.exists()){
            new ParseBookCovers().execute();
        }
        MyJSON.getData(getApplicationContext()); //read file json
        urls = GetListUrlCovers(MyJSON.getData(getApplicationContext())); // parse urls + write to array
        for (int i = 0; i < urls.size(); i++) {
            int d = i + 1;
            fileUrl = urls.get(i);
            filename = this.getFilesDir() + File.separator + "bookcover_" + d + ".jpg";
            FileLoader(fileUrl, filename);
        }
        initData();
        initializeAdapter();
    }
    private void initData() {
        covers = new ArrayList<>();
        covers.add(new Cover("booklist_1"));
        covers.add(new Cover("booklist_1"));
        covers.add(new Cover("booklist_1"));
        covers.add(new Cover("booklist_1"));
    }
    private void initializeAdapter() {
        RecyclerAdapter recyclerAdapter = new RecyclerAdapter(covers);
        recyclerView.setAdapter(recyclerAdapter);
    }
    private ArrayList<Uri> CoverLoader(ArrayList<String> urls) {
        ArrayList<Uri> urisImg = new ArrayList<>();
        for (int i = 0; i < urls.size(); i++) {
            int d = i + 1;
            filename = this.getFilesDir() + File.separator + "bookcover_" + d + ".jpg";
            ThinDownloadManager downloadManager = new ThinDownloadManager(5); //количество потоков загрузки
            Uri downloadUri = Uri.parse(urls.get(i));
            Uri destinationUri = Uri.parse(filename);
            urisImg.add(destinationUri);
            DownloadRequest downloadRequest = new DownloadRequest(downloadUri).setDestinationURI(destinationUri);
            downloadManager.add(downloadRequest);
            Log.d(LOG_TAG, String.valueOf(urisImg.get(i)));
            downloadManager.release();
        }
        return urisImg;
    }
    private void FileLoader(String fileUrl, String filename) {
        ThinDownloadManager downloadManager = new ThinDownloadManager(5); //количество потоков загрузки
        Uri downloadUri = Uri.parse(fileUrl);
        Uri destinationUri = Uri.parse(filename);
        DownloadRequest downloadRequest = new DownloadRequest(downloadUri).setDestinationURI(destinationUri);
        downloadManager.add(downloadRequest);
    }
    private class ParseBookCovers extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String resultJson = "";
        @Override
        protected String doInBackground(Void... params) {
            // получаем данные с внешнего ресурса
            try {
                URL url = new URL("http://*******.ru/todbook/booklist.json");
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                resultJson = buffer.toString();
                MyJSON.saveData(getApplicationContext(), resultJson);

            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultJson;
        }
        @Override
        protected void onPostExecute(String strJson) {
        }
    }
    private ArrayList<String> GetListUrlCovers(String strJson) {
        Log.d(LOG_TAG, strJson);
        JSONObject dataJsonObj = null;
        ArrayList<String> urls = new ArrayList<>();
        try {
            dataJsonObj = new JSONObject(strJson);
            JSONArray books = dataJsonObj.getJSONArray("books");
            for (int i = 0; i < books.length(); i++) {
                JSONObject book = books.getJSONObject(i);
                String url_book = book.getString("coverUrl");
                urls.add(url_book);// пишу урлы в ArrayList urls
                Log.d(LOG_TAG, "coverUrl: " + url_book);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return urls;
    }
}

На всякий случай вот еще лог:

11-05 22:38:28.846 12880-12880/ru.yandex.matu1.toddlersbook E/TAG: Error in Reading: /data/user/0/ru.yandex.matu1.toddlersbook/files/booklist.json (No such file or directory)
11-05 22:38:28.846 12880-12880/ru.yandex.matu1.toddlersbook E/TAG: Error in Reading: /data/user/0/ru.yandex.matu1.toddlersbook/files/booklist.json (No such file or directory)
11-05 22:38:28.846 12880-12880/ru.yandex.matu1.toddlersbook D/AndroidRuntime: Shutting down VM
11-05 22:38:28.846 12880-12919/ru.yandex.matu1.toddlersbook D/NetworkSecurityConfig: No Network Security Config specified, using platform default
11-05 22:38:28.846 12880-12880/ru.yandex.matu1.toddlersbook E/AndroidRuntime: FATAL EXCEPTION: main
                                                                              Process: ru.yandex.matu1.toddlersbook, PID: 12880
                                                                              java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.yandex.matu1.toddlersbook/ru.yandex.matu1.toddlersbook.MainActivity}: java.lang.NullPointerException: println needs a message
                                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                                                                                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                                                                                  at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                  at android.os.Looper.loop(Looper.java:154)
                                                                                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
                                                                               Caused by: java.lang.NullPointerException: println needs a message
                                                                                  at android.util.Log.println_native(Native Method)
                                                                                  at android.util.Log.d(Log.java:143)
                                                                                  at ru.yandex.matu1.toddlersbook.MainActivity.GetListUrlCovers(MainActivity.java:155)
                                                                                  at ru.yandex.matu1.toddlersbook.MainActivity.onCreate(MainActivity.java:57)
                                                                                  at android.app.Activity.performCreate(Activity.java:6662)
                                                                                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
                                                                                  at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
                                                                                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                  at android.os.Looper.loop(Looper.java:154) 
                                                                                  at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                                                  at java.lang.reflect.Method.invoke(Native Method) 
                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 
11-05 22:38:28.959 12880-12919/ru.yandex.matu1.toddlersbook D/my_log: method saveData - File writted 

По логу не могу понять, где появляется java.lang.NullPointerException: println needs a message

Answer 1

Ваша ошибка в следующем:
сразу за вызовом new ParseBookCovers().execute(); следует обращение к данным, но таск ещё не выполнился и соответственно данных ещё нет;
Нужно код после if (!file.exists()) вынести в отдельный метод и при отсутствии файла вызывать его из onPostExecute :

 protected void onCreate(Bundle savedInstanceState) {
     // ------------
     if (!file.exists()){
        new ParseBookCovers().execute();
     } else {
         continue(); // в этот метод переносим весь код, что был дальше в onCreate
     }
 }
     protected void onPostExecute(String strJson) {
         continue();
     }
READ ALSO
Запрос permission java android

Запрос permission java android

Не получается получить разрешение на использование интернета на телефоне androidПытался сделать это на android 6

223
NullPointerException при работе с TableView

NullPointerException при работе с TableView

Не могу понять в чем проблема, вроде все делаю по oracle tutorialsНо что-то не все верно получается

191