2013-08-21 3 views
0

나는 이것에 관해 약간 혼란스러워서 누군가의 도움에 정말로 감사 할 것입니다.Android : AsyncTask - doInBackground에서 어댑터를 설정할 수 없습니까?

활동 내 MainActivity - 두 개의 클래스가 있습니다 - RetrieveThumbnailsTask (AsyncTask) 및 Adapter ImageAdapter (BaseAdapter 확장)가 있습니다. 기본적으로 외부 저장소에서 이미지의 축소판을 검색하고이를 gridview에 표시합니다. 이제이 작업은 상당히 느린 것으로 판명되었으므로 (수백 개의 이미지에 대해 상당한 시간이 소요됨) AsyncTask에 축소판을 작성하기로 결정했습니다.

GridView gridview = (GridView) findViewById(R.id.gridview); 
gridview.setAdapter(new ImageAdapter(activity)); 

gridview.setOnItemClickListener(new OnItemClickListener() { 
public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
       Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show(); 
      } 
}); 

이 코드는 onPostExecute의 내부 지금

이 모든 것이 확실히 작동합니다

public class MainActivity extends Activity { 

    private Cursor cursor; 
    private Bitmap[] thumbnails; 
    private ProgressDialog pd; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     init(); 
    } 

    private void init() { 
     createProgressDialog(); 
     new RetrieveThumbnailsTask(this).execute(); 
    } 

    private void createProgressDialog() { 
     //... 
    } 

    private void createThumbnails() { 
     //... 
    } 

    private class ImageAdapter extends BaseAdapter { 

     private Context mContext; 

     public ImageAdapter(Context c) { 
      mContext = c; 
     } 

     @Override 
     public int getCount() { 
      // TODO Auto-generated method stub 
      return thumbnails.length; 
     } 

     @Override 
     public Object getItem(int position) { 
      // TODO Auto-generated method stub 
      return null; 
     } 

     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return 0; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      ImageView imageView; 
      if (convertView == null) { // if it's not recycled, initialize some attributes 
       imageView = new ImageView(mContext); 
       imageView.setLayoutParams(new GridView.LayoutParams(120, 120)); 
       imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
       imageView.setPadding(8, 8, 8, 8); 
      } 
      else { 
       imageView = (ImageView) convertView; 
      } 

      imageView.setImageBitmap(thumbnails[position]); 
      return imageView; 
     } 
    } 

    private class RetrieveThumbnailsTask extends AsyncTask<Void, Void, Boolean> { 

     private MainActivity activity; 

     public RetrieveThumbnailsTask(MainActivity a) { 
      activity = a; 
     } 

     protected void onPreExecute() { 
      pd.show(); 
     } 

     protected Boolean doInBackground(Void... params) { 
      activity.createThumbnails(); //This is the slow process that creates the thumbnails 
      return true; 
     } 

     protected void onPostExecute(Boolean b) { 
      pd.dismiss(); 
      GridView gridview = (GridView) findViewById(R.id.gridview); 
      gridview.setAdapter(new ImageAdapter(activity)); 

      gridview.setOnItemClickListener(new OnItemClickListener() { 
       public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
        Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     } 
    } 
} 

내가 이해하지 못하는 부분이 있습니다 :

코드는

/관련없는 부분은/탈락 . 그러나 그것이 doInBackground 내부에있을 때 (return true 문 바로 위), 코드는 gridview.setAdapter (new ImageAdapter (activity))에 멈 춥니 다. 앱 강제 종료. 제 질문은 - 이것이 왜 발생합니까? 설명은 무엇입니까? 나는 큰 시간을 놓치고 있어야 할 것 같은데. 고맙습니다!

+1

아마도 예외가 있습니다. 자세한 내용은 추적을 표시해야하지만 어댑터 설정은 주 스레드에서만 수행 할 수 있습니다 (많은 GUI 작업) –

+0

어댑터는 onPostExecute에서 설정되어야합니다. 'doInBackground'에서 왜 이것을 설정하겠습니까? 그로 인해 얻을 수있는 이점은 무엇입니까? – Androiderson

+0

@ Exception-al 특별한 이유는 없지만 doInBackground에서 호출되는 함수에서 모든 것을 갖기 전에 그냥 궁금해하고있었습니다. – Fygo

답변

2

gridviewUI 요소이며 당신은 당신이 setAdapter()으로 수행하는 작업이며이 onPostExecute()에서 작동 이유입니다 배경 ThreadUI를 업데이트 할 수 없습니다.

AsyncTask의 모든 방법은 doInBackground()을 제외하고 UI Thread을 실행하므로 UI 요소를 업데이트 할 수 없습니다. 그래서 만약 당신이 그것을 설정하는 데 문제가 onPostExecute() 다음 설명 해주십시오, 당신은 그것이 작동하지만. 문제가 없다면 그냥 설정하십시오.

AsyncTask Docs

+0

예, onPostExecute에서 작동합니다. 이유는 분명하지 않습니다. 설명 해줘서 고마워. – Fygo

관련 문제