2

我在回收站視圖和卡片視圖中遇到問題。我正在使用asynctask從API獲取信息,現在我只能獲得一個名稱 - 這意味着我僅在我的卡片視圖中顯示文本視圖。然而,當我加載列表時,它非常緩慢。在日誌貓中,我可以看到應用程序獲取數據的速度非常快,但在回收站視圖中顯示它需要很長時間。使用卡片視圖在回收站視圖中加載文本太慢

我添加了幾個樣本 - 從回收站視圖的適配器和持有回收視圖的片段。也許我在適配器中做了錯誤的事情。

謝謝你的幫助!

適配器:

public class PlacesListAdapter extends RecyclerView.Adapter<PlacesListAdapter.ListViewHolder>{ 
ArrayList<PlaceItem> items; 
Context context; 

public PlacesListAdapter(Context context,ArrayList<PlaceItem> placeItems){ 
    this.context = context; 
    this.items = placeItems; 
} 

public void swap(ArrayList<PlaceItem> places){ 
    items.clear(); 
    items.addAll(places); 
    notifyDataSetChanged(); 
} 

@Override 
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(context).inflate(R.layout.card_view, parent, false); 
    return new ListViewHolder(v); 
} 

@Override 
public void onBindViewHolder(ListViewHolder holder, int position) { 
    PlaceItem item = items.get(position); 
    holder.bindData(item); 
} 

@Override 
public int getItemCount() { 
    return items.size(); 
} 

public class ListViewHolder extends RecyclerView.ViewHolder{ 
    TextView title; 
    PlaceItem placeItem; 
    public ListViewHolder(View itemView) { 
     super(itemView); 
     title = (TextView) itemView.findViewById(R.id.txtTitlePlace); 
    } 

    public void bindData(PlaceItem item){ 
     this.placeItem = item; 
     title.setText(placeItem.getTitle()); 
    } 
    } 
} 

片段:

public class FragmentListPlaces extends Fragment implements View.OnClickListener { 

ArrayList<PlaceItem> placeItems; 
PlacesListAdapter adapter; 
RecyclerView list; 
EditText editName; 

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

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View v = inflater.inflate(R.layout.fragment_list_places, container, false); 
    editName = (EditText) v.findViewById(R.id.editPlaceName); 
    v.findViewById(R.id.btnGetLocations).setOnClickListener(this); 
    v.findViewById(R.id.btnSearchByText).setOnClickListener(this); 
    placeItems = new ArrayList<>(); 
    placeItems.add(new PlaceItem("Example")); 
    adapter = new PlacesListAdapter(getContext(), placeItems); 
    list = (RecyclerView) v.findViewById(R.id.placesList); 
    list.setLayoutManager(new LinearLayoutManager(getContext())); 
    list.setAdapter(adapter); 
    return v; 
} 

@Override 
public void onClick(View v) { 
    switch (v.getId()){ 
     case R.id.btnGetLocations: 
      GetUserLocation location = new GetUserLocation(); 
      location.getLocation(getActivity()); 
      adapter.swap(placeItems); 
      break; 
     case R.id.btnSearchByText: 
      // this is the method loading data with user input 
      String getNameFromUser = editName.getText().toString(); 
      searchPlaceByText(getNameFromUser); 
      adapter.swap(placeItems); 
      break; 
    } 
} 

public void searchPlaceByText(String place){ 
    // instantiate the asynctask here 
    LocationDetailsByText locationDetailsByText = new LocationDetailsByText(placeItems); 
    locationDetailsByText.execute("http://api.v3.factual.com/t/places-il?q=" + place + "&KEY=AFvDryDJmPkkgXohbpFdqkRQelT9w0HKtyEqXy3G"); 
} 

從網絡加載數據:

public class LocationDetailsByText extends AsyncTask<String, Void, String> { 

ArrayList<PlaceItem> placeItems = new ArrayList<>(); 

public LocationDetailsByText(ArrayList<PlaceItem> places){ 
    this.placeItems = places; 
} 
@Override 
protected String doInBackground(String... params) { 
    StringBuilder result = new StringBuilder(); 
    BufferedReader reader; 
    HttpURLConnection connection = null; 
    URL url; 

    String query = (params[0]); 
    try { 
     url = new URL(query); 
     connection = (HttpURLConnection)url.openConnection(); 

     if(connection.getResponseCode() != 200){ 
      return "Error!"; 
     } 

     reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

     String line = ""; 
     while((line = reader.readLine())!= null){ 
      result.append(line); 
     } 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    }finally { 
     connection.disconnect(); 
    } 
    return result.toString(); 
} 

@Override 
protected void onPostExecute(String s) { 
    PlaceItem placeItem; 
    try { 
     JSONObject root = new JSONObject(s); 
     JSONObject response = root.getJSONObject("response"); 
     JSONArray data = response.getJSONArray("data"); 

     for(int i = 0; i < data.length(); i++){ 
      JSONObject getData = data.getJSONObject(i); 
      String title = getData.getString("name"); 
      placeItem = new PlaceItem(title); 
      placeItems.add(placeItem); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
} 
+0

你可以看到這個問題:使用Android的圖像cardview正在加載很懶惰而(http://stackoverflow.com/questions/33796166/android-while-using-cardview-image-is-loading-very-lazy ) –

+0

嗨, 這個問題主要是與images..but處理我只使用文本視圖,它仍然加載速度非常slow..i找不到在論壇的任何答案,所以我想我做的這裏有什麼不對,但只是不能注意到它。這個問題正在放慢我的項目進度。 – Eran

+0

我也不斷收到這條線在日誌貓: W /查看:)requestLayout(由android.support.v7.widget.AppCompatTextView不當叫{3c56a6c7 V.ED .... ...... ID 222,45-366,118#7f0c0076 app:id/drawer_item_text}佈局過程中:運行第二個佈局傳遞 這是什麼意思? – Eran

回答

1

很少有什麼問題與您的代碼

searchPlaceByText(getNameFromUser); 
adapter.swap(placeItems); 

adapter.swap(placeItems);在您啓動AsyncTask後啓動,但您尚未下載任何內容。這是錯誤的。你應該從這裏取出adapter.swap(placeItems);,做這樣的事情,而不是:

@Override 
public void onClick(View v) { 
    switch (v.getId()){ 
     case R.id.btnGetLocations: 
      GetUserLocation location = new GetUserLocation(); 
      location.getLocation(getActivity()); 
      adapter.swap(placeItems);//also here probably 
      break; 
     case R.id.btnSearchByText: 
      // this is the method loading data with user input 
      String getNameFromUser = editName.getText().toString(); 
      searchPlaceByText(getNameFromUser); 
      break; 
    } 
} 
public void searchPlaceByText(final String place) { 
     // instantiate the asynctask here 
     LocationDetailsByText locationDetailsByText = new LocationDetailsByText(placeItems) { 

      @Override 
      protected void onPostExecute(String s) { 
       super.onPostExecute(s); 
       adapter.swap(placeItems); 
      } 
     }; 
     locationDetailsByText.execute("http://api.v3.factual.com/t/places-il?q=" + place + "&KEY=AFvDryDJmPkkgXohbpFdqkRQelT9w0HKtyEqXy3G"); 
} 

接下來的事情是,你清楚你的清單

items.clear(); 
items.addAll(places); 

這基本上也從placeItems刪除一切,因爲在這個類erlier你設置this.items = placeItems;。所以在PlacesListAdapter只是做

public void swap(ArrayList<PlaceItem> places){ 
    notifyDataSetChanged(); 
} 
2

除了@M G指出,通常會擾亂行爲的問題。 你有兩個其他的主要缺陷,我可以看到其中1)主要影響你。

1)你做所有的Json解析+移動數據到你的POJO(PlaceItem [])onPostExecute。這是錯誤的!

  • 這可以在計算
  • 這種方式非常沉重的,你創建了2對多中間對象很多GC

的,我建議將這些背景和使用GSON。

2)看起來您可能會頻繁發生大量網絡通話。這需要更好地管理從網絡流獲得的併發請求,網絡連接,線程,流和數據陣列。這可能會導致很多GC。

我會推薦使用一些爲此目的而設計的網絡庫,例如改造,抽氣或jus。這些都可以處理在後臺直接解析網絡數據到您的POJO,並最大限度地減少GC和性能。

0

在你的AsyncTask,在OnPostExcute,在它的結束通知你的適配器關於您的數據的變化,這就是爲什麼你不能看到你的數據,除非你在編輯文本,再次單擊。

相關問題