在Android中使用线程将所有手机图像加载到GridView

时间:2013-08-07 12:42:11

标签: android multithreading image load

我在Android中遇到Thread问题。我有一个CheckBox网格视图,我想加载所有图像库到这个网格。但我想加载这个线程。但当我点击加载图像程序关闭。这是我的代码。请看看并给我最好的解决方案。感谢

Add_Image.Java:

public class add_images extends Activity implements Runnable {

    private int count;
    private Bitmap[] thumbnails;
    private boolean[] thumbnailsselection;
    private String[] arrPath;
    private ImageAdapter imageAdapter;
    private String selectImages="";
    private final ProgressDialog pd = new ProgressDialog(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_images);
        pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pd.setMessage("Please Wait...");
        pd.setIndeterminate(false);
        pd.setCancelable(true);
        pd.show();
        Thread t = new Thread(add_images.this);
        t.start();
    }

    @Override
    public void run(){
        GetList();
    }

    private void GetList() {
        try {   

            final String[] columns = { MediaStore.Images.Media.DATA,
                    MediaStore.Images.Media._ID };
            final String orderBy = MediaStore.Images.Media._ID;
            Cursor imagecursor = managedQuery(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                    null, null, orderBy);
            final int image_column_index = imagecursor
                    .getColumnIndex(MediaStore.Images.Media._ID);
            this.count = imagecursor.getCount();
            this.thumbnails = new Bitmap[this.count];
            this.arrPath = new String[this.count];
            this.thumbnailsselection = new boolean[this.count];
            for (int i = 0; i < this.count; i++) {
                imagecursor.moveToPosition(i);
                final   int id = imagecursor.getInt(image_column_index);
                final   int dataColumnIndex = imagecursor
                        .getColumnIndex(MediaStore.Images.Media.DATA);
                thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
                        getApplicationContext().getContentResolver(), id,
                        MediaStore.Images.Thumbnails.MICRO_KIND, null);
                arrPath[i] = imagecursor.getString(dataColumnIndex);
                pd.setProgress(i);
            }
            GridView imagegrid = (GridView) findViewById(R.id.Add_Select_PhoneImageGrid);
            imageAdapter = new ImageAdapter();
            imagegrid.setAdapter(imageAdapter);
            imagecursor.close();
            pd.dismiss();

        } catch (Exception ex) {

        }
    }

Add_Image.Xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <Button
        android:id="@+id/btn_images_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:minWidth="110px"
        android:text="Back To Main" android:onClick="onClick" />
    <Button
        android:id="@+id/btn_images_selected"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toRightOf="@+id/btn_images_back"
        android:text="Select" android:onClick="onClick"/>

    <GridView
        android:id="@+id/Add_Select_PhoneImageGrid"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/btn_images_selected"
        android:columnWidth="90dp"
        android:gravity="center"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp" />

</RelativeLayout>

add_view_galleryitem.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageView
        android:id="@+id/add_view_thumbImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <CheckBox
        android:id="@+id/add_view_itemCheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" />

</RelativeLayout>

2 个答案:

答案 0 :(得分:0)

像这样的东西

    pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    pd.setMessage("Please Wait...");
    pd.setIndeterminate(false);
    pd.setCancelable(true);
    pd.show();
new Thread(add_images.this) {
                    @Override
                    public void run() {
                           try {
                                 // code runs in a thread
                                 activity.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                               // code runs in a UI(main) thread
                                        }
                                 });
                           } catch (final Exception ex) {
                           }
                    }
             }.start();

答案 1 :(得分:0)

如果您在崩溃时发布了堆栈跟踪,那将非常有用。它应该在logcat中显示为错误。

无论如何,从它的外观来看,你正在尝试从Android(以及许多其他GUI框架)不允许的单独线程更新GUI。您只能从GUI线程更新GUI。

一个简单的解决方案就是调用runOnUiThread,但Android SDK有更好的解决方案,可以异步加载数据并在之后更新GUI。例如,Loader将其数据加载到单独的线程中,并将结果发布到GUI线程中的LoaderCallbacks实现 。此外,LoaderManager负责在配置更改(例如,设备被轮换)和/或创建新Loader并查询后重新启动活动时恢复先前的实例Loader

对于从ContentResolver加载数据的特定情况,例如从MediaStore,您可以使用CursorLoader

Android guides对加载器如何工作以及如何使用它们有优秀的解释。 SDK中还有示例项目,例如LoaderCursor示例项目。