2016-11-04 2 views
-1

몇 가지 동일한 질문이 있다는 것을 알고 있지만, 내가 잘못하고있는 것을 파악하지 못했습니다.NetworkOnMainThreadException - Android/Java

public class MainActivity extends AppCompatActivity { 
... 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ... 
     new JsonHandler().execute(this, collection, gridArray, customGridAdapter); 
     ... 
    } 
} 

그래서 내 주요 활동에서 JSON을 돌려주는 API를 쿼리해야하고 데이터베이스를 빌드해야합니다.

그런 다음 doInBackground()에서 첫 번째 JSON을 가져 오는 getAllCards()를 호출합니다. JSON에는 더 많은 JSON 요청을위한 URL이 포함되어 있으므로보다 자세한 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; 
} 

}

그래서 지금의 문제 :

을 programm이 processCard에 도달() 나는 충분한 정보를 수집 한 경우, 나는이되는 InputStream을 만들 때 NetworkOnMainThreadException를 얻을.

내 URL에서 비트 맵을 얻고 비동기 작업을 수행하는 여러 가지 방법을 시도해 보았습니다. 모두 동일한 결과를 낳았습니다.

이 문제를 해결하는 방법을 알려 주시면 기꺼이 행복하겠습니다.

편집 : 복제본으로 표시되었으므로 : 나는 ASYNCTASK를 사용 중입니다! 나는 많은 질문을보고 거기에서 한 것을 시도했다, 그것은 효과가 없다! 와

+0

를 만들기 위해 새 스레드를 시작해야하므로 주 스레드에서해야합니다. 당신은 AsyncTask를 필요로하지 않습니다 ... –

+0

글쎄,이 예외를 줬기 때문에 AsyncTask를 시작했습니다. 그래서 저는 인터넷을 검색했고 모두가 AsyncTasc가되어야한다고 말하고있었습니다. 오류는 여전히 AsyncTask의 유무와 동일합니다 ... – Darkmessage

+0

Volleys onResponse가 기본 UI에서 다시 발생하기 때문에 오류가 발생했습니다 ... AsyncTask 외부에서 'processCard'를 호출합니다. 이 게시물 **은 ** 복제 된 것입니다. 백그라운드에서 수행되는'getAllCards' 부분 만이 발리 큐에 추가됩니다. –

답변

0

정말 익숙하지 않은 방법을 시도한 작동하지만 onResponse하지만 당신이 전화 당신이 발리를 사용하고 너무

+0

하지만 Json 메서드는 새 스레드에있는 doInBackground에서 호출됩니까? – Darkmessage

+0

@Darkmessage 배경에서 호출되는 유일한 것은 getAllCards' 콜백'onResponse'이 메인 스레드에서 다시 호출됩니다. – tyczj

관련 문제