2012-01-19 30 views
1

我剛剛開始在android上工作,看起來像我已經進入了一些多線程問題。有人可以看看下面的代碼,告訴我我在這裏做錯了什麼。使用asynctask和適配器顯示android的遠程圖像

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.
  2. 異步線程被調用5次,雖然數組中的元素只有3個
  3. 在應顯示的三張圖像中只顯示了兩張..

有人可以幫忙嗎?

+0

只是一個聲明,它在java中的習慣是,第一個單詞是小寫字母,其餘的單詞是大寫的..就像myLocalBundle。和成員變量(全局變量)標記爲mWhateverYouLike。 – JoxTraex

+0

關於bug 3,可能這可能是其中一個返回的圖像爲null。 – JoxTraex

+0

此外,您可能想要重寫getCount()以查看傳入的是哪個數字。這會讓您知道它是否存在初始適配器數據或其他問題。 – JoxTraex

回答

0
  1. 您不控制刷新視圖和重繪元素的次數。我認爲這就是從適配器多次請求元素的原因。
  2. 如第1點所示:如果多次請求元素,則異步任務將運行多次。
  3. 有些意見可能不會被繪製,因爲它們已被解僱。您不應該堅持視圖元素,因爲它可以在異步任務進入網頁時進行更改。 如果您嘗試顯示大量元素,則最終可能會在錯誤的位置看到錯誤的圖像,因爲網格中的視圖可以重複使用。

我會建議的是一個不同的機制,緩存在弱引用的結果。一旦返回一些結果,只需刷新網格並從緩存中獲取圖像 - 無需再次訪問網頁。這樣你就不會保留網格的子視圖 - 只需要網格刷新自己。

+0

感謝您的回答@ kilaka – Rasmus

+0

歡迎。我有同樣的問題,並樂意幫助別人節省一些時間。 –

相關問題