[英]Android Picasso image loading app crash when scrolls the RecyclerView
[英]Android RecyclerView freezes when image loading is done using Picasso
在我的Android應用中,主頁上有一個recycleerview,其中每個項目都包含cardviews。 首先,我調用ParseServer以獲取服務器上的數據並將其傳遞給recyclerview適配器。 我將圖像URL以及其他詳細信息傳遞給適配器類。 在我的MainActivity.java中
Parse.initialize(this, "key1", "key2");
ParsePush.subscribeInBackground("", new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
if(haveNetworkConnection()){
new task().execute();
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
從服務器獲取數據的類任務:
public class task extends AsyncTask<Void, Void, Void>{
ProgressDialog mProgressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
rel.setVisibility(View.VISIBLE);
pro.setVisibility(View.VISIBLE);
titles.clear();
images.clear();
venues.clear();
timings.clear();
urgent.clear();
}
@Override
protected Void doInBackground(Void... params) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("notices");
try {
List<ParseObject> ob = query.find();
for(ParseObject obj:ob){
String str = obj.getString("title");
String str1 = obj.getString("venue");
String str2 = obj.getString("timing");
ParseFile file = obj.getParseFile("images");
String str3 = obj.getString("urgent");
String url;
if(file!=null)
url = file.getUrl();
else{
url = "https://www.medidirect.com.au/MEDIstores/_images/no-thumb.png";
}
titles.add(str);
images.add(url);
venues.add(str1);
timings.add(str2);
urgent.add(str3);
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
AdapNotice mAdapter = new AdapNotice(MainActivity.this,titles,images,venues,timings,urgent);
if(titles.size()<1)
Toast.makeText(MainActivity.this, "Oops, Something went wrong. Please try again", 300).show();
mRecyclerView.setAdapter(mAdapter);
pro.setVisibility(View.GONE);
rel.setVisibility(View.GONE);
}
}
在AdapNotice類中,這是recyclerview適配器:
public class AdapNotice extends RecyclerView.Adapter<AdapNotice.ViewHolder>{
Activity activity;
ArrayList<String> _titles = new ArrayList<String>();
ArrayList<String> _images = new ArrayList<String>();
ArrayList<String> _venues = new ArrayList<String>();
ArrayList<String> _timings = new ArrayList<String>();
ArrayList<String> _urgents = new ArrayList<String>();
private int lastPosition = -1;
int pos;
public AdapNotice(Activity a, ArrayList<String> titles, ArrayList<String> images, ArrayList<String> venues, ArrayList<String> timings, ArrayList<String> urgent) {
activity = a;
_titles = titles;
_images = images;
_venues = venues;
_timings = timings;
_urgents = urgent;
}
public static class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
public TextView title;
public ImageView imgview,urgent;
public TextView venue,venuetext,abctext;
public TextView timing,timingtext,abc1text;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.title);
imgview = (ImageView) v.findViewById(R.id.img_notice);
venue = (TextView) v.findViewById(R.id.venue);
timing = (TextView) v.findViewById(R.id.timing);
venuetext = (TextView)v.findViewById(R.id.venuetext);
abctext = (TextView)v.findViewById(R.id.abctext);
timingtext = (TextView)v.findViewById(R.id.timingtext);
abc1text = (TextView)v.findViewById(R.id.abc1text);
urgent = (ImageView)v.findViewById(R.id.urgentstar);
}
}
@Override
public int getItemCount() {
// TODO Auto-generated method stub
if(_titles.size()<=0)
return 0;
return _titles.size();
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// TODO Auto-generated method stub
try{
holder.title.setText(_titles.get(position));
if(_urgents.get(position).contains("yes")){
holder.urgent.setVisibility(View.VISIBLE);
}
pos = position;
if(!_venues.get(position).contentEquals("---")){
holder.venuetext.setVisibility(View.VISIBLE);
holder.venue.setVisibility(View.VISIBLE);
holder.abctext.setVisibility(View.VISIBLE);
holder.venue.setText(_venues.get(position));
}
if(!_timings.get(position).contentEquals("---")){
holder.timingtext.setVisibility(View.VISIBLE);
holder.timing.setVisibility(View.VISIBLE);
holder.abc1text.setVisibility(View.VISIBLE);
holder.timing.setText(_timings.get(position));
}
Target target = new Target() {
@Override
public void onPrepareLoad(Drawable arg0) {
// TODO Auto-generated method stub
Animation anim = AnimationUtils.loadAnimation(activity, R.anim.rotate);
holder.imgview.setImageResource(R.drawable.loading);
holder.imgview.startAnimation(anim);
}
@Override
public void onBitmapLoaded(Bitmap arg0, LoadedFrom arg1) {
// TODO Auto-generated method stub
holder.imgview.clearAnimation();
holder.imgview.setImageBitmap(arg0);
Log.i("completed", pos+" completed");
storeDB obj = new storeDB(_titles.get(pos), _venues.get(pos), _timings.get(pos), DbBitmapUtility.getBytes(arg0), _urgents.get(pos));
obj.execute();
}
@Override
public void onBitmapFailed(Drawable arg0) {
// TODO Auto-generated method stub
holder.imgview.clearAnimation();
holder.imgview.setImageResource(R.drawable.error);
}
};
Picasso.with(activity).load(_images.get(position)).into(target);
}catch(Exception e){
e.printStackTrace();
}
}
private class storeDB extends AsyncTask<Void, Void, Void>{
String title,venue,timing,urgent;
byte[] image;
public storeDB(String one, String two, String three, byte[] four, String five){
title = one;
venue = two;
timing = three;
image = four;
urgent = five;
}
@Override
protected Void doInBackground(Void... params) {
SQLiteHandler handler = new SQLiteHandler(activity);
handler.addNotice(title, venue, timing, image, urgent);
handler.close();
return null;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item, parent, false);
Animation animation = AnimationUtils.loadAnimation(activity, (arg1>lastPosition)?R.anim.up_from_bottom:R.anim.down_from_top);
v.startAnimation(animation);
ViewHolder vh = new ViewHolder(v);
return vh;
}
}
我將圖片網址傳遞到畢加索庫,該庫將圖片加載到目標中。 直到畢加索未提取圖像為止,我正在顯示另一個加載圖像並為其提供旋轉動畫效果。
有時候,即使圖像是由畢加索加載的,它也不會在imageview中顯示。 旋轉動畫停止並且加載的圖像也未顯示在imageview中。 此外,加載imageview時,主視圖有時會凍結。
因此,我該如何解決此問題並使我的應用程序運行更流暢?
提前致謝。
更新我發現凍結問題是由於對目標的引用不足。 我以很強的參考力解決了它,但是我該如何解決掛起的問題呢? 當我滾動時,App被掛起了一段時間。
您可以使用一種簡單的方法
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView);
在加載圖像之前將顯示placholder圖像,如果發生錯誤,則將顯示錯誤圖像
UPDATE存儲在數據庫中只需編寫這么多樣板代碼
class MyTarget implements Target {
private ImageView imageView;
public MyTarget(ImageView imageView) {
this.imageView = imageView;
}
@Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
this.imageView.setImageBitmap(bitmap);
//store your bitmap as you were storing
}
}
接着
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(new MyTarget(imageView));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.