2017-08-21 24 views
0

我正在製作一個應用程序,該應用程序使用外部API顯示足球聯賽的表格。 我正在使用一個包含recyclerview(顯示聯盟表)的片段,並且使用AsyncTask從網絡獲取實際數據。我有兩個問題:Android工作室 - 從AsynTask獲取數據到主線程

  1. 在片段的onCreateView方法,我設置recyclerview。我把適配器作爲一個局部變量,然後,在AsyncTask的onPostExecute方法中,我將結果(表格數據,在這裏,它是一個TeamLeagueStandings數組)傳遞給適配器。然後,問題是適配器由於某種原因保持爲空,我不明白爲什麼。

  2. 雖然它獲取數據,我希望它顯示progressBar,並在AsyncTask方法,onPreExecute和onPostExecute,我更改進度欄的可見性值。出於某種原因,進度條根本沒有顯示出來。爲什麼會發生?

這是一個包含recyclerview(對錶本身),以及裏面的IT-的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); 

     } 
    } 
    } 

這是我得到的實際類數據和處理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; 
} 

}

謝謝! :)

+0

嘗試創建recyclerview和執行的AsyncTask前的適配器。在你的情況下,現在你可以在初始化之前從服務器獲得響應。 – matip

+0

我改變了一點。現在我只在onPostExecute和onCreateView中處理recyclerview,我只是調用AsyncTask,而且它工作得很好。謝謝! – Shayts

回答

0

您可以使用doinBackground期間獲得的數據onProgressUpdate FUNC .. 例子:

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

我改變了一點。現在我只在onPostExecute和onCreateView中處理recyclerview,我只是調用AsyncTask,而且它工作得很好。謝謝! – Shayts