Логика приложения: проверяю существование файла, если его нет - вызываю внутренний класс 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
Ваша ошибка в следующем:
сразу за вызовом 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();
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Не получается получить разрешение на использование интернета на телефоне androidПытался сделать это на android 6
Не могу понять в чем проблема, вроде все делаю по oracle tutorialsНо что-то не все верно получается