简体   繁体   English

Android-从线程返回值

[英]Android - return value from thread

I have a function that retrieve images from the resource and display it in a GridView . 我有一个从资源检索图像并将其显示在GridView Everithing works fine but due to a performance issue I would like to create at runtime thumbs so I create a new ProgressDialog to let know the user that the app is working: 一切都可以正常工作,但是由于性能问题,我想在运行时创建拇指,因此我创建了一个新的ProgressDialog来告知用户该应用程序正在运行:

import java.util.ArrayList;

import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;

import com.italiandevteam.chuck.adapter.GridViewAdapter;
import com.italiandevteam.chuck.model.ImageItem;

public class GalleriaPersonaggio extends Fragment{

    Integer personaggio = null;
    private ProgressDialog progressDialog;
    TypedArray imgs = null;

    final ArrayList imageItems = new ArrayList();

    public GalleriaPersonaggio( int personaggio ){

        this.personaggio = personaggio;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        int id = getIdPersonaggio();

        View rootView = null;

        try {
                rootView = inflater.inflate(R.layout.gallery_grid, container, false);
            } 
        catch (InflateException e) {
        }

        final GridView gridView = (GridView) rootView.findViewById(R.id.gridView);
        GridViewAdapter customGridAdapter = new GridViewAdapter(getActivity(), R.layout.gallery_row, getData(personaggio));
        gridView.setAdapter(customGridAdapter);

        gridView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//              HashMap<String, Object> hm = gridView.getAdapter().getPosition(position);
//
//                 String imgPath = (String) hm.get("flag"); //get downloaded image path
//              Intent i = new Intent(getActivity(), MostraImmagine.class); //start new Intent to another Activity.
//              i.putExtra("ClickedImagePath", imgPath ); //put image link in intent.
//              startActivity(i);
            }

    });

        return rootView;
    }

    public int getIdPersonaggio(){
        return this.personaggio;
    }

    private ArrayList getData(int personaggio) {

        // retrieve String drawable array

        switch( personaggio )
        {        
            case 1:{
                imgs = getResources().obtainTypedArray(R.array.chuck_ids);
                break;
            }
            case 2:{
                imgs = getResources().obtainTypedArray(R.array.sarah_ids);
                break;
            }

            default:{
                imgs = getResources().obtainTypedArray(R.array.chuck_ids);
            }

        }



        final ProgressDialog ringProgressDialog = ProgressDialog.show(getActivity(), "Please wait ...", "Loading Images ...", true);
                ringProgressDialog.setCancelable(true);
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {

                                int THUMBNAIL_HEIGHT = 100;
                                int THUMBNAIL_WIGHT = 100;
                                for (int i = 0; i < imgs.length(); i++) 
                                {
                                    Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), imgs.getResourceId(i, -1));
                                    bitmap = Bitmap.createScaledBitmap(bitmap, THUMBNAIL_HEIGHT, THUMBNAIL_WIGHT, false);
//                                  ByteArrayOutputStream baos = new ByteArrayOutputStream();  
//                                  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
//                                  byte[] imageData = baos.toByteArray();
//                                  InputStream is = new ByteArrayInputStream(imageData);
//                                  Bitmap b = BitmapFactory.decodeStream(is);
                                    imageItems.add(new ImageItem(bitmap, "Image#" + i));
                                }

                            } catch (Exception e) {

                            }
                            ringProgressDialog.dismiss();
                        }

                    }).start();


        return imageItems;

    }
}

The problem is that at the end the code doesn't return anything, the GridView is empty, if I remove the thread it works well. 问题是,最后代码没有返回任何内容, GridView为空,如果我删除线程,它将很好地工作。

Thread instances can not return values, since the run method has return type void. 线程实例不能返回值,因为run方法的返回类型为void。 What you can do is to to implement the delegate pattern (Listener in Android), or switch to the Callable interface and Executors . 您可以做的是实现delegate模式(Android中的监听器),或切换到Callable接口和Executors Please be aware that waiting for the return type could not make sense. 请注意,等待返回类型没有什么意义。 If you something: 如果您有以下事情:

Pseudo code UIThread: 伪代码UIThread:

variable = threadInstance.getResult();

you made an asynchronous call, synchronous 您进行了异步调用,同步

As pointed by 323go, you can use AsyncTask (much better IMHO). 正如323go所指出的,您可以使用AsyncTask (更好的IMHO)。 Create an internal class like this: 创建一个这样的内部类:

private class MyAsyncTask extends AsyncTask<ArrayList<String>, Integer, Long> {
    ...
}

Integer is used to update a progress dialog (if you don't need one, just put Void instead); Integer用于更新进度对话框(如果您不需要,请放Void代替); Long is the result of DoInBackground method. Long是DoInBackground方法的结果。 Launch your AsyncTask like this: 像这样启动您的AsyncTask:

new MyAsyncTask().execute(passing);

Now i don't know what you are aiming, but if you follow the link suggested by 323go or this tutorial , you can improve your code. 现在我不知道您的目标是什么,但是如果您遵循323go或本教程建议的链接,则可以改进代码。

EDIT 编辑

After 323go comments, it is better to pass your ArrayList of object in AsyncTask constructor: 在323go注释之后,最好在AsyncTask构造函数中传递对象的ArrayList:

new MyAsyncTask(passing).execute();

Of course in your AsyncTask class you have to create an internal variable: 当然,在AsyncTask类中,您必须创建一个内部变量:

...
private ArrayList<Object> myArrayList;

private MyAsyncTask(ArrayList<Object> anArrayList) {
    myArrayList = anArrayList;
}
...

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

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