【问题标题】:WAIT_FOR_CONCURRENT_GC blockedWAIT_FOR_CONCURRENT_GC 被阻塞
【发布时间】:2014-03-20 14:56:28
【问题描述】:

我有四个同步任务,它们从片段的onCreateView() 执行,这些线程正在从服务器检索数据,在每四个线程内,有超过 15 个线程用于从服务器获取图像。当时 GC 阻塞了我的四个线程超过 1 分半钟......所有四个 async 任务在 preExecute() 方法他们工作正常......但在 doInBackground() 它阻塞超过 1 分钟。

在此先感谢.......

 03-20 19:48:19.250: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
 03-20 19:48:21.020: E/Image(6416): 1
 03-20 19:48:21.760: D/dalvikvm(6416): GC_EXPLICIT freed 112K, 8% free 26454K/28551K,                  
 03-20 19:48:23.489: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
  03-20 19:48:26.749: D/dalvikvm(6416): GC_EXPLICIT freed 81K, 7% free 26605K/28551K,     paused 66ms+23ms, total 3256ms
 03-20 19:48:28.010: E/Image(6416): 2
 03-20 19:48:28.470: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
 03-20 19:48:31.220: D/dalvikvm(6416): GC_EXPLICIT freed 76K, 7% free 26762K/28551K,  paused 26ms+25ms, total 2751ms
 03-20 19:48:32.760: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
03-20 19:48:35.020: E/Image(6416): 1
 03-20 19:48:35.369: D/dalvikvm(6416): GC_EXPLICIT freed 75K, 6% free 26918K/28551K,     paused 49ms+44ms, total 2610ms
 03-20 19:48:36.950: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
 03-20 19:48:39.690: D/dalvikvm(6416): GC_EXPLICIT freed 77K, 6% free 27074K/28551K, paused 43ms+24ms, total 2660ms
03-20 19:48:41.240: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
 03-20 19:48:42.020: E/Image(6416): 2
 03-20 19:48:43.860: D/dalvikvm(6416): GC_EXPLICIT freed 75K, 5% free 27231K/28551K, paused 71ms+48ms, total 2615ms
 03-20 19:48:45.740: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC blocked 0ms
03-20 19:48:48.641: D/dalvikvm(6416): GC_EXPLICIT freed 76K, 5% free 27388K/28551K, paused 37ms+46ms, total 2901ms
 03-20 19:48:49.031: E/Image(6416): 1

03-20 19:48:50.240: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC 阻塞 0ms 03-20 19:48:52.950: D/dalvikvm(6416): GC_EXPLICIT freed 77K, 4% free 27543K/28551K, paused 49ms+44ms,总共2708ms 03-20 19:48:54.550: D/dalvikvm(6416): WAIT_FOR_CONCURRENT_GC 阻塞 0ms

图片下载代码...

公共类 ImageDownloaderTask 扩展 AsyncTask{

private final WeakReference<ImageView> imageViewReference;

private final WeakReference<ProgressBar> progreeBarReferance;

public ImageDownloaderTask(ImageView imageView) {
    imageViewReference = new WeakReference<ImageView>(imageView);
    progreeBarReferance=null;
}

public ImageDownloaderTask(ImageView imageView, ProgressBar progressBar){
    progreeBarReferance= new WeakReference<ProgressBar>(progressBar);
    imageViewReference = new WeakReference<ImageView>(imageView);
}

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
    if(progreeBarReferance != null){
        ProgressBar progressBar=progreeBarReferance.get();
        progressBar.setVisibility(View.VISIBLE);
    }

}

@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
    // params comes from the execute() call: params[0] is the url.
    return downloadBitmap(params[0]);
}

@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
    if (isCancelled()) {
        bitmap = null;
    }

    if(progreeBarReferance != null){
        ProgressBar progressBar=progreeBarReferance.get();
        if(progressBar != null){
            progressBar.setVisibility(View.GONE);
        }

    }


    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {

            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
            } else {
                imageView.setImageDrawable(imageView.getContext().getResources()
                        .getDrawable(R.drawable.ic_launcher));

            }
        }

    }
}

static Bitmap downloadBitmap(String url) {
    final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
    final HttpGet getRequest = new HttpGet(url);
    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error " + statusCode
                    + " while retrieving bitmap from " + url);
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                System.gc();

                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                entity.consumeContent();
            }
        }
    }catch (Exception e) {
        // Could provide a more explicit error message for IOException or
        // IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
    }  catch(Throwable e){

        Log.e("From Throwable", "");
        e.printStackTrace();

    }finally {
        if (client != null) {
            client.close();
        }
    }
    return null;
}

}

在一个片段上有四个列表视图。每个listview 处理单独的asynctask 每个列表项调用ImageDownloaderASynctask

在列表视图项上设置图像的代码 以下代码对于所有四个listview 适配器都是相同的

@Override
public View getView(int position, View convertView, ViewGroup arg2) {
    // TODO Auto-generated method stub

    if (convertView == null) {
        LayoutInflater mInflater = (LayoutInflater)
                context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        convertView = mInflater.inflate(R.layout.my_swaps_item, null);


    }
    ImageView imgIcon = (ImageView)convertView.findViewById(R.id.my_swap_item_ImageView_image);
    TextView title=(TextView)convertView.findViewById(R.id.my_swaps_item_textview_title);
    ProgressBar progressBar=(ProgressBar)convertView.findViewById(R.id.my_swaps_item_progressBar);

    title.setText(followersList.get(position).first_name);

    new ImageDownloaderTask(imgIcon,progressBar).execute(followersList.get(position).imageUrl);

    return convertView;

async 从服务器获取数据的任务,用于单个片段上的四个列表视图

    public class GetProfileDataAsyncTask extends AsyncTask<Void, Void, Void>{
    private String[] ids;
    private String[] params;
    private JMYSwapsList jmySwapList;
    private int flag;
    private JMyFriendsList jmyFriendsList;
    private JMyFollowerList jMyFollowerList;
    private JProfileList jProfileList;

    public GetProfileDataAsyncTask(String[] ids, String[] params, int flag) {
        // TODO Auto-generated constructor stub
        this.ids=ids;
        this.params=params;
        this.flag=flag;
    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();

        Log.e("0", "1");
        if(flag==0)
        {
            mySwapProgressBar.setVisibility(View.VISIBLE);
        }
        if(flag==1){
            myFriendProgressBar.setVisibility(View.VISIBLE);
        }
        if(flag == 2){
            myFollowersProgressBar.setVisibility(View.VISIBLE);
        }
        if(flag == 3){
            friendRequestProgressBar.setVisibility(View.VISIBLE);
        }
        Log.e("0", "2");
    //  System.gc();
    }



    @Override
    protected Void doInBackground(Void... arg0) {
        // TODO Auto-generated method stub

        Log.e("1", "1");
        if(flag == 0){




            String response= Profiles.getDataFromServer(ids, params, Constants.My_SWAP_URL);

            Log.e("2", "1");
            jmySwapList=Profiles.parseMySwap(response);

            if(jmySwapList != null){
                if(jmySwapList.Success != null){
                    for (JSwap jSwap: jmySwapList.Success) {
                        System.out.println("from do Person  "+ jSwap.name);
                        mySwapList.add(new MySwapsData(jSwap.name,"http://"+ jSwap.swap_image_thumb.replace("\\","").replace(" ", "%20")));
                    }
                }else{
                    if(jmySwapList.noData != null){
                        Log.e("Profile From My Swap", jmySwapList.noData);
                    }
                }
            }
        }

        Log.e("1", "2");
        if(flag == 1){

            String response= Profiles.getDataFromServer(ids, params, Constants.MY_FRIENDS_URL);
            Log.e("2", "2");
            jmyFriendsList=Profiles.parseMyFriends(response);

            if(jmyFriendsList != null){

                if(jmyFriendsList.Success != null){

                    for (JFriend jFriend: jmyFriendsList.Success) {
                        System.out.println("from do Person  "+ jFriend.first_name);
                        myFrindsList.add(new FriendAdapterData(jFriend.first_name,"http://"+ jFriend.user_image_thumb.replace("\\","").replace(" ", "%20")));
                    }

                }else{

                    if(jmyFriendsList.noData != null){
                        Log.e("Profile From My Friends", jmyFriendsList.noData);
                    }
                }
            }

        }
        Log.e("1", "3");
        if(flag == 2){
            String response= Profiles.getDataFromServer(ids, params, Constants.MY_FOLLOWERS_URL);
            Log.e("2", "3");
            jMyFollowerList=Profiles.parseMyFollowers(response);

            if(jMyFollowerList != null){

                if(jMyFollowerList.Success != null){
                    for (JFollower jFollower: jMyFollowerList.Success) {
                        System.out.println("from do Person  "+ jFollower.user_id);
                        //  myFrindsList.add(new FriendAdapterData(jFollower.user_id,"http://"+ jFriend.user_image_thumb.replace("\\","").replace(" ", "%20")));

                        myFollowerList.add(new FollowerAdapterData(jFollower.first_name,"http://"+ jFollower.user_image_thumb.replace("\\","").replace(" ", "%20")));
                    }
                }else{
                    if(jMyFollowerList.noData != null){
                        Log.e("Profile From My Follower", jMyFollowerList.noData);
                    }
                }

            }

        }
        Log.e("1", "4");
        if(flag == 3){

        }

        if(flag == 4){
            String response= Profiles.getDataFromServer(ids, params, Constants.GET_PROFILE);
            jProfileList=Profiles.parseProfile(response);
            if(jProfileList != null){
                if(jProfileList.Success != null){
                    for(JProfile jProfile: jProfileList.Success){
                        System.out.println("from do Person  "+ jProfile.first_name);
                    }
                }else{
                    if(jProfileList.noData != null){
                        Log.e("from Profile", jProfileList.noData);
                    }
                }
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);

        //MySwaps
        if(flag==0){
            mySwapAdapter.notifyDataSetChanged();
            mySwapProgressBar.setVisibility(View.INVISIBLE);
        }
        //Friends
        if(flag==1){
            myFriendAdapter.notifyDataSetChanged();
            myFriendProgressBar.setVisibility(View.INVISIBLE);
        }
        //Follower
        if(flag == 2){
            myFollowerAdapter.notifyDataSetChanged();
            myFollowersProgressBar.setVisibility(View.INVISIBLE);
        }
        //Friend Rquest
        if(flag == 3){
            friendRequestProgressBar.setVisibility(View.INVISIBLE);
        }
        if(flag == 4){
            String imageUrl=null;

            if(jProfileList != null){
                for(JProfile jProfile: jProfileList.Success){
                    //System.out.println("from do Person  "+ jProfile.first_name);
                    //  imageUrl=jProfile.user_image_thumb;
                    imageUrl="http://"+ jProfile.user_image_thumb.replace("\\","").replace(" ", "%20");
                }
            }
            if(imageUrl != null)
            {
                new ImageDownloaderTask(myProfileImage).execute(imageUrl);
            }
        }

    }

}

【问题讨论】:

  • 如果您可以发布您的代码,我们可以获得概览。但您似乎使用了太多内存。
  • 请注意,如果您在 API 13 (Honeycomb) 及更高版本中使用 AsyncTask,AsyncTask 将按顺序执行而不是并行执行。我的猜测是其中一个线程占用了资源,从而导致 GC 发生。再次检查您的线程。

标签: android multithreading


【解决方案1】:

尝试换行:

new ImageDownloaderTask(myProfileImage).execute(imageUrl);

到:

new ImageDownloaderTask(myProfileImage).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageUrl);

它允许您的任务在不同的线程上运行。

第二个问题是:System.gc(); 你为什么要这样做?在正常情况下(并且下载图像绝对不是火箭科学)垃圾收集器只能由系统运行,而不是由用户运行。

【讨论】:

  • 谢谢......现在它的工作正常......我也有一个问题......当我滚动列表查看它再次下载已经下载的图像....这个问题是因为我在 getView 方法中执行异步任务.....???\
  • 是的,每次在列表中显示列表项时都会调用ListView 中的getView 方法。 developer.android.com/training/displaying-bitmaps/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多