2017-08-21 4 views
0

Je fais une application qui montre des tables de ligues de football en utilisant une API externe. Je travaille avec un fragment, qui contient une vue de recyclage (pour afficher la table de classement), et j'utilise une asyncTask pour obtenir les données réelles du web. J'ai 2 problèmes à cela:Android studio - Obtenir des données de AsynTask à thread principal

  1. Dans la méthode onCreateView du fragment, je suis la mise recyclerview. Je place l'adaptateur en tant que variable locale, puis, à l'intérieur de la méthode onPostExecute dans la tâche AsyncTask, je transmets les résultats (les données de la table, ici un tableau de TeamLeagueStandings) à l'adaptateur. Ensuite, le problème est que l'adaptateur reste pour une raison quelconque, et je ne comprends pas pourquoi. Pendant que j'obtiens les données, je veux qu'elles affichent progressBar, et dans les méthodes AsyncTask onPreExecute et onPostExecute, je change la valeur de visibilité de la barre de progression. Pour une raison quelconque, la barre de progression n'apparaît pas du tout. Pourquoi cela se passe-t-il?

C'est le fragment qui contient recyclerview (pour montrer la table elle-même), et à l'intérieur it- la AsyncTask (DownloadTask):

public class TableStandingsFragment extends Fragment { 
    private static final String LEAGUETOLAUNCH = "league"; 
    private TeamAdapter adapter; 
    private ProgressBar progressBar; 
    private String league; 
    private OnFragmentInteractionListener mListener; 

    public TableStandingsFragment() { 
     // Required empty public constructor 
    } 


    public static TableStandingsFragment newInstance(String param1) { 
     TableStandingsFragment fragment = new TableStandingsFragment(); 
     Bundle args = new Bundle(); 
     args.putString(LEAGUETOLAUNCH, param1); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     // Gets the argument of the fragment. This will tell us which league table to show 
     //using the method "GeturlTeamsByArg", which gives the URL, and then using AsyncTask to get 
     //the actual data, with the given url. 
     super.onCreate(savedInstanceState); 
     if (getArguments() != null) { 
      league = getArguments().getString(LEAGUETOLAUNCH); 
     } 
    } 



    public URL GeturlTeamsByArg() { 

     //Returns the correct URL of the required league table, depends on the variable "league" 

     URL url=null; 
     if (league == "" || league == null) 
      return null; 
     switch (league) { 
      case ("Premier League"): 
       url = League_standings.GetPLQuery(); 
       break; 
      case ("Football League Championship"): 
       url = League_standings.GetChampionshipQuery(); 
       break; 
      case ("Eredvise"): 
       url = League_standings.GetEredviseQuery(); 
       break; 
      case ("Ligue 1"): 
       url = League_standings.GetLigue1Query(); 
       break; 
      case ("Ligue 2"): 
       url = League_standings.GetLigue2Query(); 
       break; 
      case ("Bundesliga"): 
       url = League_standings.GetBundesligaQuery(); 
       break; 
      case ("2. Bundesliga"): 
       url = League_standings.GetSecBundesligaQuery(); 
       break; 
      case ("Primera División"): 
       url = League_standings.GetSpanishQuery(); 
       break; 
      case ("Serie A"): 
       url = League_standings.GetSeriaAQuery(); 
       break; 
      case ("Primeira Liga"): 
       url = League_standings.GetPortugeseQuery(); 
       break; 
     } 
     return url; 
    } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
      // StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
      //StrictMode.setThreadPolicy(policy); 
      View v= inflater.inflate(R.layout.fragment_recyclerview, container, false); 
      progressBar = v.findViewById(R.id.progressBar); 
      DownloadTask downloadTask=new DownloadTask(); 
      try{ 
       downloadTask.execute(GeturlTeamsByArg()); 
       RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.recyler_teams); 
       recyclerView.setHasFixedSize(true); 
       recyclerView.setAdapter(adapter); 
       recyclerView.addItemDecoration(new VerticalSpaceItemDecorator(30)); 
       LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); 
       layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
       recyclerView.setLayoutManager(layoutManager); 
       } 
      catch (Exception e){ 
       Log.d("error",e.toString()); 
      } 




      return v; 
     } 


    // TODO: Rename method, update argument and hook method into UI event 
    public void onButtonPressed(Uri uri) { 
     if (mListener != null) { 
      mListener.onFragmentInteraction(uri); 
     } 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof OnFragmentInteractionListener) { 
      mListener = (OnFragmentInteractionListener) context; 
     } else { 
      throw new RuntimeException(context.toString() 
        + " must implement OnFragmentInteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 
    class VerticalSpaceItemDecorator extends RecyclerView.ItemDecoration { 

     private final int spacer; 

     public VerticalSpaceItemDecorator(int spacer) { 
      this.spacer = spacer; 
     } 

     @Override 
     public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
      super.getItemOffsets(outRect, view, parent, state); 
      outRect.bottom = spacer; 
     } 
    } 

    public interface OnFragmentInteractionListener { 
     // TODO: Update argument type and name 
     void onFragmentInteraction(Uri uri); 
    } 



    public class DownloadTask extends AsyncTask<URL, Void, TeamLeagueStandings[]> { 

     // COMPLETED (26) Override onPreExecute to set the loading indicator to visible 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      progressBar.setVisibility(View.VISIBLE); 
     } 

     @Override 
     protected TeamLeagueStandings[] doInBackground(URL... params) { 
      URL searchUrl = params[0]; 
      TeamLeagueStandings[] results = null; 
      try { 
       results = League_standings.LeagueStandingsArray(searchUrl); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      return results; 
     } 

     @Override 
     protected void onPostExecute(TeamLeagueStandings[] results) { 
      progressBar.setVisibility(View.INVISIBLE); 
      adapter=new TeamAdapter(results); 

     } 
    } 
    } 

C'est la classe où je reçois le réel données et faire face à la JSON:

public class League_standings { 

//League codes in the url 
private final static int PLCODE = 445; 
private final static int CHAMPIONSHIPCODE = 446; 
private final static int EREDVISECODE = 449; 
private final static int LIGUE1CODE = 450; 
private final static int LIGUE2CODE = 451; 
private final static int BUNDESLIGACODE = 452; 
private final static int SECBUNDESLIGACODE = 453; 
private final static int SPANISHCODE = 455; 
private final static int SERIAACODE = 456; 
private final static int PORTUGESECODE = 457; 
private static String nationCode = ""; 
private static String querystr = ""; 
private static URL url = null; 
private static TeamLeagueStandings[] teams; 


public static URL GetPLQuery() { 
    // Returns the full URL of the search query combined with the PL code. 
    nationCode = Integer.toString(PLCODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetChampionshipQuery() { 
    // Returns the full URL of the search query combined with the championship code. 
    nationCode = Integer.toString(CHAMPIONSHIPCODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetEredviseQuery() { 
    // Returns the full URL of the search query combined with the eredvise code. 
    nationCode = Integer.toString(EREDVISECODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetLigue1Query() { 
    // Returns the full URL of the search query combined with the ligue1 code. 
    nationCode = Integer.toString(LIGUE1CODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetLigue2Query() { 
    // Returns the full URL of the search query combined with the ligue2 code. 
    nationCode = Integer.toString(LIGUE2CODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetBundesligaQuery() { 
    // Returns the full URL of the search query combined with the bundesliga code. 
    nationCode = Integer.toString(BUNDESLIGACODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetSecBundesligaQuery() { 
    // Returns the full URL of the search query combined with the second bundesliga code. 
    nationCode = Integer.toString(SECBUNDESLIGACODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetSpanishQuery() { 
    // Returns the full URL of the search query combined with the Spanish league code. 
    nationCode = Integer.toString(SPANISHCODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetSeriaAQuery() { 
    // Returns the full URL of the search query combined with the seria A code. 
    nationCode = Integer.toString(SERIAACODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 

public static URL GetPortugeseQuery() { 
    // Returns the full URL of the search query combined with the Portugese league code. 
    nationCode = Integer.toString(PORTUGESECODE); 
    querystr = "competitions/" + nationCode + "/leagueTable"; 
    url = Data.BuildUrl(querystr); 
    return url; 
} 


public static TeamLeagueStandings[] LeagueStandingsArray(URL url) throws IOException, JSONException { 

    //Gets the full url of the requested league table, should look like: 
    //"http://api.football-data.org/v1/competitions/445/leagueTable" 
    //Processing the JSON data from the API, then returns an array which 
    //contains the teams of the league 
    //that was requested, in THE ORDER OF THE TABLE!!! 

    String results = Data.GetResponseFromHttpUrl(url); 
    JSONObject resultsJSON = new JSONObject(results); 
    JSONArray teamsJson = resultsJSON.getJSONArray("standing"); 
    int length = teamsJson.length(); 
    teams = new TeamLeagueStandings[length]; 
    // name,games,wins,draws,losses,GD,points, pic 
    for (int i = 0; i < length; i++) { 


     JSONObject object = teamsJson.getJSONObject((i)); 
     TeamLeagueStandings team = new TeamLeagueStandings(); 
     team.setPlace(Integer.toString(object.getInt("position"))); 
     team.setTeamName(object.getString("teamName")); 
     team.setCurGames(Integer.toString(object.getInt("playedGames"))); 
     team.setWins(Integer.toString(object.getInt("wins"))); 
     team.setDraws(Integer.toString(object.getInt("draws"))); 
     team.setLosses(Integer.toString(object.getInt("losses"))); 
     team.setGoalDifference(Integer.toString(object.getInt("goalDifference"))); 
     team.setPoints(Integer.toString(object.getInt("points"))); 
     team.setImgString(object.getString("crestURI")); 
     if (team.getTeamName().toLowerCase().contains("FC".toLowerCase())) { 
      team.setTeamName(team.getTeamName().replace("FC", "")); 
     } 
     if (team.getTeamName().endsWith(" ")) { 
      team.setTeamName(StringUtils.strip(team.getTeamName())); 

     } 
     if (team.getTeamName().length() > 12) { 
      String name = team.getTeamName(); 
      for (int j = 12; j < name.length(); j++) { 
       char c = name.charAt(j); 
       if (c == ' ') { 
        name = name.substring(0, j) + "\n" + name.substring(j + 1); 
        team.setTeamName(name); 
        break; 
       } 
      } 
     } 
     teams[i] = team; 
    } 

    return teams; 
} 

}

Merci !! :)

+0

Essayez de créer recyclerview et son adaptateur avant d'exécuter AsyncTask. Dans votre cas, vous pouvez obtenir une réponse du serveur avant qu'ils ne soient initiés. – matip

+0

Je l'ai modifié un peu. Maintenant, je ne traite de la vue de recyclage que dans onPostExecute, et dans onCreateView, je ne fais qu'appeler l'AsyncTask, et ça marche très bien. Merci! – Shayts

Répondre

0

Vous pouvez utiliser obtenir des données onProgressUpdate func .. pendant doinBackground Exemple:

class MyTask extends AsyncTask<Void, Void, Void> { 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected Void doInBackground(Void... voids) { 
      onProgressUpdate(); 
      return null; 
     } 

     @Override 
     protected void onProgressUpdate(Void... values) { 
      super.onProgressUpdate(values); 
      // here you can get data from MainThread 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
     } 
    } 
+0

Je l'ai changé un peu. Maintenant, je ne traite de la vue de recyclage que dans onPostExecute, et dans onCreateView, je ne fais qu'appeler l'AsyncTask, et ça marche très bien. Merci! – Shayts