简体   繁体   English

Android Java在BaseAdapter中创建新线程不起作用

[英]Android Java creating new thread in BaseAdapter not working

I'm developing an android app, for that app I have an activity that loads data from a database, that includes text and images. 我正在开发一个android应用程序,为此应用程序我有一个从数据库加载数据(包括文本和图像)的活动。 The objective is that those images are displayed in circle, and until now everything is ok. 目的是将这些图像显示为圆形,到目前为止一切正常。

The problem is that when I start the activity is receives the data with an AsyncTask class and shows the "Loading" dialog but when it passes to my BaseAdapter, it blocks until all the images are loaded, what makes the app to be lazy. 问题是,当我开始活动时,将使用AsyncTask类接收数据并显示“正在加载”对话框,但是当它传递给我的BaseAdapter时,它将阻塞直到所有图像加载完毕,这才使应用程序变得懒惰。 What can I do to solve this? 我该怎么解决?

Below you have all my code process. 下面是我所有的编码过程。

NotificationsActivity (LoadNotifications AsyncTask) NotificationsActivity(LoadNotifications AsyncTask)

class LoadNotifications extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(Notifications.this);
        pDialog.setMessage("Loading..");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    protected String doInBackground(String... args) {

        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("token", token));

        Log.d("TOKEN", token);

        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(getMyNotificationsURL,
                "POST", params);

        try { // Trying to get notifications

            // Getting Array of notifications
            notifications = json.getJSONArray("notifications");

            userImage = new String[notifications.length()];
            message = new String[notifications.length()];
            param = new String[notifications.length()];
            type = new String[notifications.length()];
            timestamp = new String[notifications.length()];

            // Looping through all notifications
            for (int i = 0; i < notifications.length(); i++) {

                JSONObject c = notifications.getJSONObject(i);

                    try{
                        userImage[i] = c.getString("userImage");
                    } catch(Exception e){
                        userImage[i] = "system";
                    }


                message[i] = c.getString("message");
                param[i] = c.getString("param");
                type[i] = c.getString("type");
                timestamp[i] = c.getString("timestamp");

                Log.d("message", message[i]);

            } // End for

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(String file_url) {

        if (notifications.length() > 0) {

            // updating UI from Background Thread
            runOnUiThread(new Runnable() {

                public void run() {
                    // dismiss the dialog after getting all videos
                    pDialog.dismiss();

                    list = (ListView) findViewById(R.id.notifications_list);
                    NotificationsAdapter adapter = new NotificationsAdapter(
                            mActivity, userImage, message, param, type,
                            timestamp);
                    list.setAdapter(adapter);
                }
            });

        } else {

            pDialog.dismiss();

            Toast.makeText(getApplicationContext(),
                    getString(R.string.noNotifications), Toast.LENGTH_LONG)
                    .show();
            finish();

        }
    } // Close PostExecute
} // Close LoadNotifications

NotificationsAdapter (The for cycle in constructor is what loads the images) NotificationsAdapter(构造器中的for循环是加载图像的原因)

public class NotificationsAdapter extends BaseAdapter{

private Activity activity;
private String[] usersImage, messages, params, types, timestamps;
private Bitmap[] loadedImages;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;

public boolean isOnline() {

    ConnectivityManager connectivity = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity != null) 
    {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null) 
            for (int i = 0; i < info.length; i++) 
                if (info[i].getState() == NetworkInfo.State.CONNECTED)
                {
                    return true;
                }

    }
    return false;
}

public NotificationsAdapter(final Activity activity, String[] userImage, String[] messages, String[] params, String[] types, String[] timestamps) {
    this.activity       = activity;
    this.usersImage     = userImage;
    this.messages       = messages;
    this.params         = params;
    this.types          = types;
    this.timestamps     = timestamps;

    final ImageHelper imageHelper = new ImageHelper();
    loadedImages = new Bitmap[getCount()];

   /*(new Thread(new Runnable() {

        @Override
        public void run() {
            activity.runOnUiThread(new Runnable() {
                public void run() {*/
                    for (int i=0; i<getCount(); i++){
                        loadedImages[i] = imageHelper.downloadImageTaskOnly(usersImage[i]);
                    }
                    /*areImagesLoaded=true;
                }
            });
        }
    })).start();*/


    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader=new ImageLoader(activity.getApplicationContext());
}

public int getCount() {
    return messages.length;
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {

    ImageHelper imageHelper = new ImageHelper();

    View vi=convertView;
    if(convertView==null)
        vi = inflater.inflate(R.layout.notifications_item, null);

    ImageView   userImage   = (ImageView)   vi.findViewById(R.id.userImage);
    TextView    message     = (TextView)    vi.findViewById(R.id.notification_message);
    TextView    param       = (TextView)    vi.findViewById(R.id.notification_param);
    TextView    type        = (TextView)    vi.findViewById(R.id.notification_type);
    TextView    timestamp   = (TextView)    vi.findViewById(R.id.notification_timestamp);

    if (!isOnline()) {
        Toast.makeText(activity,
                activity.getString(R.string.noInternetConnection),
                Toast.LENGTH_SHORT).show();
    } else {
        if(usersImage[position].equalsIgnoreCase("system")){
            Bitmap icon = BitmapFactory.decodeResource(activity.getResources(), R.drawable.vidytape_icon);
            userImage.setImageBitmap(imageHelper.BigRoundedShape(icon));
        } else {
            userImage.setImageBitmap(imageHelper.BigRoundedShape(loadedImages[position]));
        }

    }

    message.setText(messages[position]);
    param.setText(params[position]);
    type.setText(types[position]);
    timestamp.setText(timestamps[position]);
    return vi;
}

}

ImageHelper 影像助手

downloadImageTaskOnly method downloadImageTaskOnly方法

public Bitmap downloadImageTaskOnly(String url){
    Log.e("IMAGE HELPER", url);

    try {
        return new DownloadImageTaskOnly().execute(url).get();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

downloadImageTaskOnly AsyncTask downloadImageImageOnly AsyncTask

private class DownloadImageTaskOnly extends AsyncTask<String, Void, Bitmap> {

    protected Bitmap doInBackground(String... urls) {
        Log.e("IMAGE HELPER", "DOWNLOAD ONLY");
        String urldisplay = urls[0];
        Log.e("IMAGE HELPER", urldisplay);
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }
} // Close DownloadImageTaskOnly

BigRoundedShape 大圆形状

public Bitmap BigRoundedShape(Bitmap scaleBitmapImage) {
    // TODO Auto-generated method stub
    int targetWidth = 250;
    int targetHeight = 300;
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
            Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
            Path.Direction.CCW);

    canvas.clipPath(path);
    Bitmap sourceBitmap = scaleBitmapImage;
    canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
            sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
            targetHeight), null);
    return targetBitmap;
}

My goal is to able the user to use the app and the images that weren't already loaded, still loading in background 我的目标是使用户能够使用应用程序和尚未加载的图像,但仍在后台加载

It's so slow because of 因为这么慢

return new DownloadImageTaskOnly().execute(url).get();

.get() is always waiting for the task completion. .get()始终等待任务完成。 Feels like this tutorial can help you http://developer.android.com/training/displaying-bitmaps/process-bitmap.html 喜欢本教程的人可以帮助您http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

You can try to pass used imageview into asynctask, pass the result to onPostExecute in bitmap and there set the image, so you don't need to wait in the main thread, just start the task. 您可以尝试将使用过的imageview传递给asynctask,将结果传递给bitmap中的onPostExecute并在那里设置图像,因此您无需在主线程中等待,只需启动任务即可。 Some problems will be caused by concurrency, there you can use the second part of tutorial which works with this case. 并发会引起一些问题,您可以在本案例中使用本教程的第二部分。

If you're just downloading images, i'd recommend you to use Picasso ( http://square.github.io/picasso/ ) or even Ion ( https://github.com/koush/ion ) which are libraries that allow you to easily download and even transform an image while allowing you to use both a Memory and Disk Cache. 如果您只是下载图像,我建议您使用Picasso( http://square.github.io/picasso/ )甚至Ion( https://github.com/koush/ion ),它们是允许您轻松下载甚至转换映像,同时允许您同时使用内存和磁盘缓存。

Hope it helps 希望能帮助到你

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

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