나는 이것에 관해 약간 혼란스러워서 누군가의 도움에 정말로 감사 할 것입니다.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))에 멈 춥니 다. 앱 강제 종료. 제 질문은 - 이것이 왜 발생합니까? 설명은 무엇입니까? 나는 큰 시간을 놓치고 있어야 할 것 같은데. 고맙습니다!
아마도 예외가 있습니다. 자세한 내용은 추적을 표시해야하지만 어댑터 설정은 주 스레드에서만 수행 할 수 있습니다 (많은 GUI 작업) –
어댑터는 onPostExecute에서 설정되어야합니다. 'doInBackground'에서 왜 이것을 설정하겠습니까? 그로 인해 얻을 수있는 이점은 무엇입니까? – Androiderson
@ Exception-al 특별한 이유는 없지만 doInBackground에서 호출되는 함수에서 모든 것을 갖기 전에 그냥 궁금해하고있었습니다. – Fygo