2012-01-19 10 views
1

私はAndroidで作業し始めているところですが、いくつかのマルチスレッドの問題があるようです。誰かが下のコードを見て、私がここで間違っていることを教えてください。asynctaskとアダプターを使用してリモートイメージを表示する

public class TestHttpActivity extends Activity { 
/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    URL theurl=null; 
    try { 
     theurl = new URL("http://myurlpath/androidimages"); 
    } catch (MalformedURLException e) { 

     Log.w("alice","malformed"); 
    } 
    GridView gallery=(GridView)findViewById(R.id.wowgridview); 
    String[] imagesarray=new String[]{"1.jpg","2.jpg","3.jpg"}; 
    TheAsyncAdapterNew imgAdapter=new TheAsyncAdapterNew(this, imagesarray,theurl); 
    gallery.setAdapter(imgAdapter); 

}} 

asyncadapterは以下の通りです: -

public class TheAsyncAdapterNew extends ArrayAdapter<String> { 
private Activity mycontext; 
private String[] myimagesarray; 
private URL myurl; 
private Hashtable<Integer,ImageView> thegreatviewholders; 
public TheAsyncAdapterNew(Activity context,String[] imagesarray,URL theurl) { 
    super(context, R.layout.theadapterlayout,imagesarray); 
    mycontext=context; 
    myimagesarray=imagesarray; 
    myurl=theurl; 
    thegreatviewholders=new Hashtable<Integer,ImageView>(); 
} 
@Override 
public View getView(int position,View convertview,ViewGroup theparent){ 

    View myview=convertview; 
    String mylocalurlstring=myimagesarray[position]; 
    MyviewHolder theholder; 
    if(myview==null){ 
     LayoutInflater inflater=mycontext.getLayoutInflater(); 
     myview=inflater.inflate(R.layout.theadapterlayout, null,true); 
     ImageView mylocalimageview=(ImageView) myview.findViewById(R.id.icon); 
     theholder=new MyviewHolder(); 
     theholder.theimageview=mylocalimageview; 
     myview.setTag(theholder); 
    }else{ 
     theholder=(MyviewHolder)myview.getTag(); 

    } 
    thegreatviewholders.put(position,theholder.theimageview); 
    Bundle thebundle=new Bundle(); 
    thebundle.putString("thelocalurl",mylocalurlstring); 
    thebundle.putInt("theposition",position); 
    new Thethreadasynctask().execute(thebundle);  
    return myview; 
    } 


    protected static class MyviewHolder{ 
      protected ImageView theimageview; 
       } 

public class Thethreadasynctask extends AsyncTask<Bundle, Void,Integer> { 
    Hashtable<Integer,Bitmap> theimagehashmap; 

    @Override 
    protected Integer doInBackground(Bundle... mybundle) { 
     String mylocalurl=mybundle[0].getString("thelocalurl"); 
     Integer theposition=mybundle[0].getInt("theposition"); 
     URL themainurl=null; 
     theimagehashmap=new Hashtable<Integer,Bitmap>(); 
     try{ 
      themainurl=new URL(myurl,mylocalurl); 

     }catch (MalformedURLException es){ 
      es.printStackTrace(); 
     } 
     try{ 
      HttpURLConnection myurlconnection=(HttpURLConnection)themainurl.openConnection(); 
      myurlconnection.setDoInput(true); 
      myurlconnection.connect(); 
      InputStream is=myurlconnection.getInputStream(); 
      Bitmap bmImg=BitmapFactory.decodeStream(is); 
      Bundle mylocalbundle=new Bundle(); 
      mylocalbundle.putParcelable("theimage",bmImg); 
      mylocalbundle.putInt("thepos",theposition); 
      theimagehashmap.put(theposition,bmImg); 
     }catch(IOException e){ 
      Log.e("alice","ioexception"); 
     } 
     return theposition; 
    } 
protected void onPostExecute(Integer myposition){ 
    Bitmap myimage=theimagehashmap.get(myposition); 
    ImageView thegreatview=thegreatviewholders.get(myposition); 
    thegreatview.setImageBitmap(myimage); 
} 

}} 

バグ: -

  1. 私は、アレイアダプタのループをログインすると、私はそれは三つの要素の配列を横断見ます0,1,2のように0に戻ってから0に戻ります。
  2. 配列内の要素は3つだけですが、非同期スレッドは5回呼び出されています。
  3. 唯一の2が表示され、表示されるようになっている3枚の画像のうち
  4. ..

誰かが助けてくださいことはできますか?

+0

これはjavaの慣習では、最初の単語は小文字で残りの単語は大文字であるとします。myLocalBundleのように。また、メンバ変数(グローバル)にはmWhateverYouLikeというラベルが付けられています。バグ3については – JoxTraex

+0

、潜在的にこれは返されたイメージの1つである可能性があります。 – JoxTraex

+0

また、getCount()をオーバーライドして、どの番号が渡されるかを確認することもできます。これにより、最初のアダプタのデータに問題があるかどうかを知ることができます。 – JoxTraex

答えて

0
  1. ビューをリフレッシュして要素を再描画する回数を制御しません。私はそれが要素がアダプターから何度も要求される理由だと思う。
  2. ポイント1と同じように、要素が複数回要求された場合、非同期タスクは複数回実行されます。
  3. 一部のビューは、すでに終了しているため表示されない場合があります。非同期タスクがWebに向かう間に変更することができるため、ビュー要素を保持しないでください。 多くの要素を表示しようとすると、間違った位置に間違ったイメージが表示されることがあります。グリッド内のビューを再利用できるためです。

私は、キャッシュの結果が弱い参照と異なるメカニズムであることを示唆しています。いくつかの結果が返されると、グリッドをリフレッシュするだけで、画像はキャッシュから取り込まれます。この方法では、グリッドのサブビューを保持しません。グリッド自体をリフレッシュするよう要求します。

+0

お返事ありがとうございます@kilaka – Rasmus

+0

ようこそ。私は同じ問題を抱えており、誰かが時間を節約できるように喜んでいました。 –

関連する問題