0

私はこれについて少し混乱しているので、誰かの助けに本当に感謝しています.

アクティビティがあります-MainActivity、アクティビティ内にRetrieveThumbnailsTask(AsyncTask)とアダプターImageAdapter(BaseAdapterを拡張)の2つのクラスがあります。私は基本的に、外部ストレージから画像のサムネイルを取得し、それらをグリッドビューで表示しています。これは非常に遅いことが判明したため (何百もの画像の場合、かなりの時間がかかります)、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更新することはできません。これは、あなたが行っていることであり、 で機能する理由です。UIThreadsetAdapter()onPostExecute()

を除くすべてのメソッドがAsyncTask実行されるため、要素を更新できないのはこれだけです。そのため、設定に問題がある場合は、機能すると言いましたが、それが何であるかを説明してください. 問題がなければ、そこに設定してください。UI ThreaddoInBackground()UIonPostExecute()

AsyncTask ドキュメント

于 2013-08-21T22:08:29.293 に答える