Я знаю, что есть некоторые одинаковые вопросы, но я просто не мог понять, что я делаю неправильно.NetworkOnMainThreadException - Android/Java
public class MainActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
new JsonHandler().execute(this, collection, gridArray, customGridAdapter);
...
}
}
Так в моей основной деятельности мне нужно для запроса API, который возвращает JSON, и я должен обрабатывать, что строить свою базу данных.
Затем в doInBackground() Я вызываю getAllCards(), который получает первый JSON. Поскольку JSON содержит URL-адреса для большего количества запросов JSON, у меня есть несколько методов, каждый из которых запрашивает более подробный JSON.
public final class JsonHandler extends AsyncTask {
private final String urlCards = "https://api.gwentapi.com/v0/cards/";
private final String urlSpecificCard = "https://api.gwentapi.com/v0/cards/:id";
private Context context;
private Collection collection;
private ArrayList<Card> gridArray;
private CustomGridViewAdapter customGridAdapter;
public JsonHandler(Context context, Collection collection, ArrayList<Card> gridArray, CustomGridViewAdapter customGridAdapter){
this.context = context;
this.collection = collection;
this.gridArray = gridArray;
this.customGridAdapter = customGridAdapter;
}
public JsonHandler(){
this.context = null;
this.collection = null;
this.gridArray = null;
this.customGridAdapter = null;
}
private void getAllCards() throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, urlCards, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
generateCollection(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void getSpecificCard(final String cardURL) throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, cardURL, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
processCard(response, collection);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void generateCollection(JSONObject response) throws RuntimeException {
try {
JSONArray array = response.getJSONArray("results");
for(int i = 0; i < array.length();i++){
JSONObject object = array.getJSONObject(i);
String cardURL = object.getString("href");
getSpecificCard(cardURL);
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private void processCard(JSONObject response, Collection collection){
try {
String id = response.getString("id");
EnumFaction faction = EnumFaction.valueOf(response.getJSONObject("faction").getString("name").toUpperCase());
EnumType type = null;
EnumRarity rarity = null;
EnumLane lane = null;
EnumLoyalty loyalty = null;
String name = response.getString("name");
String text = response.getString("text");
String imagePath = "https://api.gwentapi.com/media/\" + id + \"_small.png";
URL url = new URL(imagePath);
InputStream inputStream = url.openConnection().getInputStream();
Bitmap image = BitmapFactory.decodeStream(inputStream);
Card card = new Card(id, faction, type, rarity, lane, loyalty, name, text, null, imagePath, 0);
collection.addCard(card);
gridArray.add(card);
customGridAdapter.notifyDataSetChanged();
} catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
@Override
protected Object doInBackground(Object[] params) {
context = (Context) params[0];
collection = (Collection) params[1];
gridArray = (ArrayList<Card>) params[2];
customGridAdapter = (CustomGridViewAdapter) params[3];
getAllCards();
return null;
}
}
Так что теперь к проблеме:
Когда программа достигает processCard(), когда я собрал достаточно информации, я получаю NetworkOnMainThreadException, когда я создаю InputStream.
Я пробовал так много разных методов, чтобы получить растровое изображение из моего URL-адреса и различные методы для выполнения асинхронной задачи - все это приводит к одному и тому же результату.
Если бы вы могли показать мне, как решить эту проблему, я был бы счастлив.
Редактировать: Поскольку он получил обозначение как дубликат: Я использую ASYNCTASK! Я просмотрел много вопросов и попробовал, что они там сделали, это не сработает!
Вы используете Volley. Вам не нужен AsyncTask ... –
Ну, я запустил AsyncTask, потому что он дал мне это исключение. Поэтому я обыскал Интернет, и все говорили, что это должен быть AsyncTasc. Ошибка по-прежнему совпадает с или без AsyncTask ... – Darkmessage
Ваша ошибка в том, что Volleys onResponse происходит на основном пользовательском интерфейсе ... Вы вызываете 'processCard' вне AsyncTask. Этот пост ** ** является дубликатом. Единственная часть 'getAllCards', сделанная в фоновом режиме, добавляет к очереди Volley. –