【发布时间】:2014-09-23 16:07:00
【问题描述】:
当我在任何 imageView 上调用 setImageBitmap() 时,它会滞后于 UI。我正在使用 listView 所以我必须在滚动时设置一个 imageView。请不要建议使用 Picasso 或其他图片下载助手,因为该问题与下载问题无关,并且对使用此类库没有帮助。
编辑:
适配器:
public class GönderiItemAdapter extends BaseAdapter{
private final Activity mActivity;
private final Vector<String> mVeri;
private boolean mProfil = false;
private boolean mKullanıcı;
private boolean mArama = false;
private Profil mProfilBilgi;
private String mAramaString;
public GönderiItemAdapter( Activity pActivity, String[] pVeri, boolean pKullanıcı, Profil pProfililgi ){
this(pActivity, pVeri);
mProfil = true;
mKullanıcı = pKullanıcı;
mProfilBilgi = pProfililgi;
}
public GönderiItemAdapter( Activity pActivity, final String[] pVeri, String pAramaString ){
this(pActivity, pVeri);
mAramaString = pAramaString;
mArama = true;
}
public GönderiItemAdapter( Activity pActivity, final String[] pVeri){
if( Ayarlar.sGönderiler == null )
Ayarlar.yükleGönderiler( pActivity );
mActivity = pActivity;
mVeri = new Vector<String>();
for( int i = 0; i < pVeri.length; ++i )
mVeri.add( pVeri[ i ] );
mProfil = false;
}
public void ekleÜst( String[] pVeri ){
for( int i = pVeri.length - 1; i >= 0; --i ){
Gönderi gönderi = Ayarlar.alGönderi( pVeri[ i ], mActivity, false);
if( !gönderi.mGönderenId.equals( "-1" ) )
mVeri.add( 0 , pVeri[ i ] );
}
}
public void ekleAlt( String[] pVeri, final TextView pMetin ){
for( int i = 0; i < pVeri.length; ++i ){
Gönderi gönderi = Ayarlar.alGönderi( pVeri[ i ], mActivity, false);
if( gönderi.mGönderenId.equals( "-1" ) )
mActivity.runOnUiThread( new Runnable() {
@Override
public void run() {
pMetin.setText( R.string.dahayok );
}
} );
else
mVeri.add( pVeri[ i ] );
}
}
public void al( ){
GenelEşzamansızİşlem giş = new GenelEşzamansızİşlem();
giş.arkaplanİşlem = new Thread( new Runnable() {
@Override
public void run() {
for( int i = 0; i < mVeri.size(); ++i )
Ayarlar.alGönderi( mVeri.get( i ), mActivity, false);
}
} );
if( Araçlar.mobilVeri(mActivity) )
giş.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
else
giş.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
static public void al2( final String[] pVeri, final Activity pActivity ){
GenelEşzamansızİşlem giş = new GenelEşzamansızİşlem();
giş.arkaplanİşlem = new Thread( new Runnable() {
@Override
public void run() {
if( Ayarlar.sGönderiler == null )
Ayarlar.yükleGönderiler(pActivity);
Vector<String> idVector = new Vector<String>();
for( int i = 0; i < pVeri.length; ++i )
if( !Ayarlar.sGönderiler.containsKey( pVeri[i] ) )
idVector.add( pVeri[i] );
String[] idArray = new String[ idVector.size() ];
for( int i = 0; i < idArray.length; ++i )
idArray[ i ] = idVector.get( i );
if( idArray.length > 0 )
Ayarlar.alTopluGönderi(idArray, pActivity);
}
} );
try{
giş.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get();
}catch( Exception e ){
e.printStackTrace();
}
}
public void güncelle( ){
for( int i = 0; i < mVeri.size(); ++i ){
Ayarlar.alGönderi( mVeri.get( i ), mActivity, false).güncelle( mActivity );
}
}
@Override
public int getCount(){
if( mProfil )
return mVeri.size() + 1;
return mVeri.size();
}
@Override
public int getViewTypeCount(){
return 2;
}
@Override
public Object getItem(int arg0) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position){
if( mProfil && position == 0 )
return 1;
else
return 0;
}
@Override
public boolean areAllItemsEnabled(){
return false;
}
@Override
public boolean isEnabled( int position ){
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) mActivity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if( mProfil && position == 0 )
{
View v = inflater.inflate( R.layout.header_profil, null);
final Button sağ = (Button) v.findViewById( R.id.sag );
View line1 = v.findViewById( R.id.line1);
final Button orta = (Button) v.findViewById( R.id.orta );
View line2 = v.findViewById( R.id.line2);
final Button sol = (Button) v.findViewById( R.id.sol );
if( mKullanıcı ){
sağ.setVisibility( View.VISIBLE );
sağ.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
( ( ExplorerActivity )mActivity ).yeniGönderi();
}
} );
sağ.setText( R.string.yeniGonderi );
}
else{
sağ.setVisibility( View.GONE );
line2.setVisibility( View.GONE );
if( !Ayarlar.sFavoriler.contains( mProfilBilgi.mID ) )
sol.setText( R.string.favoriEkle );
else
sol.setText( R.string.favoriCikar );
sol.setVisibility( View.VISIBLE );
sol.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
( ( ExplorerActivity )mActivity ).favori( mProfilBilgi.mID );
if( !Ayarlar.sFavoriler.contains( mProfilBilgi.mID ) )
sol.setText( R.string.favoriEkle );
else
sol.setText( R.string.favoriCikar );
}
} );
}
v.findViewById( R.id.profil ).setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
( ( ExplorerActivity )mActivity ).gösterProfil( mProfilBilgi );
}
} );
return v;
}
else{
if( mProfil )
position -= 1;
View v;
Gönderi g;
if( convertView == null ){
v = inflater.inflate( R.layout.gonderi_liste_nesnesi, null);
g = new Gönderi();
g.mAnaDüzen = (LinearLayout) v;
g.mProfilFotoğrafı = (CircularImageView) v.findViewById( R.id.profil_photo );
g.mGönderenAdı = (TextView) v.findViewById( R.id.gonderen_adi );
g.mGönderiZamanı = (TextView) v.findViewById( R.id.gonderi_tarihi );
g.mDönem = (TextView) v.findViewById( R.id.gonderen_donemi );
g.mGönderi = (TextView) v.findViewById( R.id.gonderi );
g.mBeğen = (TextView) v.findViewById( R.id.begen );
g.mBeğeniText = (TextView) v.findViewById( R.id.begeniSayi );
v.setTag( g );
}
else{
g = (Gönderi) convertView.getTag();
v = convertView;
}
final Gönderi gönderi = Ayarlar.alGönderi( mVeri.get( position ), mActivity, false);
g.mGönderenAdıString = gönderi.mGönderenAdıString;
g.mDüzenliTarih = gönderi.mDüzenliTarih;
g.mDönemString = gönderi.mDönemString;
g.mGönderiHamMetin = gönderi.mGönderiHamMetin;
g.mBeğeniTextString = gönderi.mBeğeniTextString;
g.mBeğeni = gönderi.mBeğeni;
g.mBeğenildi = gönderi.mBeğenildi;
g.mBeğeniVerisi = gönderi.mBeğeniVerisi;
g.mGönderenId = gönderi.mGönderenId;
g.mBeğeniSayısı = gönderi.mBeğeniSayısı;
g.mGönderiId = gönderi.mGönderiId;
g.ayarla( mArama, mAramaString, mActivity);
if( !mArama ){
g.beğeniİşlemler( mActivity );
if( g.mBeğenildi ){
g.mBeğen.setOnClickListener( g.mBeğenmeİşlem );
g.mBeğen.setText( R.string.hoslanma );
}
else
g.mBeğen.setOnClickListener( g.mBeğenİşlem );
final Gönderi foo = g;
g.mBeğeniText.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
final Dialog dialog = new Dialog( mActivity );
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_begeni);
ListView liste = (ListView) dialog.findViewById( R.id.liste );
Vector<Profil> profiller = new Vector<Profil>();
for( int i = 0; i < foo.mBeğeni.size(); ++i ){
Profil p = Ayarlar.alProfil( foo.mBeğeni.get( i ).mGönderenID , mActivity);
Log.w( "id" , p.mID);
if( p != null && !p.mID.equals( Ayarlar.sMevcutId ) )
profiller.add( p );
}
KartAdapter adapter = new KartAdapter(mActivity, profiller, mActivity, dialog);
liste.setAdapter( adapter );
if( profiller.size() != 0 )
dialog.show();
}
} );
g.mProfilFotoğrafı.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
((ExplorerActivity) mActivity).açProfil( gönderi.mGönderenId );
}
});
g.mGönderenAdı.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
((ExplorerActivity) mActivity).açProfil( gönderi.mGönderenId );
}
});
}
else{
g.mAnaDüzen.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View arg0) {
((ExplorerActivity) mActivity).açGönderi( gönderi.mGönderiId );
}
});
}
return v;
}
}
}
【问题讨论】:
-
这很可能是垃圾收集器启动了,因为图像占用了它想要回收的内存。如果您不提供有关位图性质的任何信息(大小、来源、每个列表项是否不同...),则无法回答您的问题。
-
它们是从服务器加载的,大小不同,每个项目也不同,但我是否从资源中设置可绘制并不重要
-
由于您使用的是 ListView,我假设您在其中有某种缩略图。也许您正在加载一个大位图(不是样本大小)以便将其放置在那里。但是如果没有用于执行此操作的代码,我无法给出任何建议。您能否发布代码如何获取位图以及如何将其传递给 ImageView?如果你发布你的 ListView 适配器也会很有帮助。
-
如果你真的想要,我可以发布适配器,但它真的很复杂,并且可以与其他类一起使用,我正在使用 Picasso 加载位图。当我看到它以这种方式滞后时,我尝试使用毕加索将图像加载到位图中,然后将位图设置为 imageview。但是每当我调用 ImageView.setImageBitmap() 或 setImageDrawable 时它都会滞后
-
如果 gc 在没有 setImageBitmap 的情况下启动,那么您遇到的问题不仅仅是图像,使用 Traceview 可能是首先要解决的问题。如果 Android 想要释放一些内存,那么 gc 就会启动,如果应用程序分配了很多内存,这种情况会更频繁地发生,例如通过向 ListView 添加许多或大图像,但当然可能有无数不同的原因。无论如何,您还需要查看您的应用程序的内存使用情况,我会使用 MAT (eclipse.org/mat)。
标签: android imageview android-imageview