0

我对此有点困惑,所以我非常感谢有人的帮助。

我有一个活动 - MainActivity,在活动内部我有两个类 - RetrieveThumbnailsTask(AsyncTask)和一个适配器 ImageAdapter(扩展 BaseAdapter)。我基本上只是从外部存储中检索图像的缩略图并在网格视图中显示它们。现在证明这很慢(对于数百张图像需要相当长的时间),所以我决定在 AsyncTask 中创建缩略图。

代码是/不相关部分遗漏/:

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();
                }
            });
        }
    }
}

我不明白的部分是这样的:

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 中时,一切正常。但是当它在 doInBackground 内部(就在 return true 语句上方)时,代码挂在 gridview.setAdapter(new ImageAdapter(activity)); 并且应用程序强制关闭。所以我的问题是 - 为什么会发生这种情况?解释是什么?我想我一定错过了一些重要的事情。谢谢!

4

1 回答 1

3

gridview是一个UI元素,你不能UI在背景上更新Thread你正在做的事情,setAdapter()这就是它在onPostExecute().

所有的方法都AsyncTask运行在UI Thread除了,doInBackground()所以这是唯一一个你不能更新UI元素的方法。因此,如果您在设置它时遇到问题,onPostExecute()请解释它是什么,尽管您说它有效。如果没有问题,那就把它放在那里。

AsyncTask 文档

于 2013-08-21T22:08:29.293 回答