2016-11-04 4 views
-1

Я знаю, что есть некоторые одинаковые вопросы, но я просто не мог понять, что я делаю неправильно.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! Я просмотрел много вопросов и попробовал, что они там сделали, это не сработает!

+0

Вы используете Volley. Вам не нужен AsyncTask ... –

+0

Ну, я запустил AsyncTask, потому что он дал мне это исключение. Поэтому я обыскал Интернет, и все говорили, что это должен быть AsyncTasc. Ошибка по-прежнему совпадает с или без AsyncTask ... – Darkmessage

+0

Ваша ошибка в том, что Volleys onResponse происходит на основном пользовательском интерфейсе ... Вы вызываете 'processCard' вне AsyncTask. Этот пост ** ** является дубликатом. Единственная часть 'getAllCards', сделанная в фоновом режиме, добавляет к очереди Volley. –

ответ

0

не очень знакомы с тем, как залп работает, но onResponse но быть в основном потоке, так что вам нужно, чтобы начать новую нить, чтобы сделать этот вызов слишком

+0

Но Json-методы вызываются из doInBackground, который находится в новом потоке? – Darkmessage

+0

@Darkmessage Единственное, что вызывается в фоновом режиме, это ваш 'getAllCards' обратный вызов' onResponse' вызывается обратно в основной поток – tyczj

Смежные вопросы