简体   繁体   English

Android:AsyncTask - 无法在doInBackground中设置适配器?

[英]Android: AsyncTask - cannot set adapter in doInBackground?

I am a bit confused about this so I would really appreciate somebody's help. 我对此有点困惑,所以我真的很感激有人的帮助。

I have an activity - MainActivity, inside of the activity I have two classes - RetrieveThumbnailsTask (AsyncTask) and an adapter ImageAdapter (extends BaseAdapter). 我有一个活动 - MainActivity,在活动内部我有两个类 - RetrieveThumbnailsTask(AsyncTask)和一个适配器ImageAdapter(扩展BaseAdapter)。 I am basically just retrieving the thumbnails of the images from the external storage and showing them in a gridview. 我基本上只是从外部存储器中检索图像的缩略图并在gridview中显示它们。 Now this proved to be quite slow (for hundreds of images it takes quite a time) so I decided to create the thumbnails in an AsyncTask. 现在这被证明是非常慢的(对于数百张图片需要相当长的时间)所以我决定在AsyncTask中创建缩略图。

The code is /irrelevant parts left out/: 代码是/无关的部分遗漏/:

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

The part I don't understand is this: 我不明白的部分是:

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

Now when this code is inside of onPostExecute, everything works alright. 现在当这段代码在onPostExecute中时,一切正常。 But when it is inside doInBackground (right above the return true statement), the code hangs on gridview.setAdapter(new ImageAdapter(activity)); 但当它在doInBackground内部(返回true语句的正上方)时,代码挂起在gridview.setAdapter(new ImageAdapter(activity)); and the app force closes. 并且app力关闭。 So my question is - why does this happen? 所以我的问题是 - 为什么会这样? What is the explanation? 解释是什么? I guess I must be missing something big time. 我想我一定会错过很多时间。 Thank you! 谢谢!

gridview is a UI element and you can't update the UI on a background Thread which is what you are doing with setAdapter() and is why it works in onPostExecute() . gridview是一个UI元素,你不能在后台Thread上更新UI ,这是你在setAdapter()中所做的,也是它在onPostExecute()工作的onPostExecute()

All methods of AsyncTask run on the UI Thread except for doInBackground() so that is the only one which you can't update UI elements. 除了doInBackground()之外, AsyncTask所有方法都在UI Thread上运行,因此这是唯一一个无法更新UI元素的方法。 So if you have a problem with setting it in onPostExecute() then please explain what it is, although you said it works. 因此,如果你在onPostExecute()设置它有问题,那么请解释它是什么,虽然你说它有效。 If there is no problem then just set it there. 如果没有问题,那就把它设置在那里。

AsyncTask Docs AsyncTask文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM