简体   繁体   English

Android:该应用程序可能在其主线程上做了大量工作

[英]Android : The application may be doing too much work on its main thread

I'm trying to load a video thumbnail from url into a grid view. 我正在尝试将视频缩略图从url加载到网格视图中。 Everything works fine, but I'm getting this message "/Choreographer: Skipped 46 frames! The application may be doing too much work on its main thread." 一切正常,但我收到此消息:“ /编排:跳过46帧!该应用程序可能在其主线程上做太多工作。”

I know it has something to do with the thumbnail loading in the main thread, but I couldn't find out how to fix this. 我知道这与主线程中的缩略图加载有关,但是我找不到解决方法。

I'm also using a device to test. 我也在使用一种设备进行测试。

public class ThumbAdapter  extends ArrayAdapter<Videos> {

    Context context;
    int ressource;
    ThumbAdapter_Holder holder=new ThumbAdapter_Holder();

    public ThumbAdapter(Context context, int resource, ArrayList<Videos> videoList) {
        super(context, resource, videoList);
        this.context=context;
        this.ressource=resource;

    }


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

        View view=convertView;
        if (view==null){

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(ressource,parent,false);

            holder.video_thum = (ImageView) view.findViewById(R.id.video_thum);

            view.setTag(holder);
        }
        else {
            holder=(ThumbAdapter_Holder) view.getTag();
        }

        try {
            holder.video_thum.setImageBitmap(retriveVideoFrameFromVideo(getItem(position).getURL()));
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return view;
    }


    class ThumbAdapter_Holder{
       ImageView video_thum ;

    }

    public static Bitmap retriveVideoFrameFromVideo(String videoPath) throws Throwable {
        Bitmap bitmap = null;
        MediaMetadataRetriever mediaMetadataRetriever = null;
        try
        {
            mediaMetadataRetriever = new MediaMetadataRetriever();
            if (Build.VERSION.SDK_INT >= 14)
                mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
            else
                mediaMetadataRetriever.setDataSource(videoPath);
            //   mediaMetadataRetriever.setDataSource(videoPath);
            bitmap = mediaMetadataRetriever.getFrameAtTime();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new Throwable(
                    "Exception in retriveVideoFrameFromVideo(String videoPath)"
                            + e.getMessage());

        } finally {
            if (mediaMetadataRetriever != null) {
                mediaMetadataRetriever.release();
            }
        }
        return bitmap;
    }
}

The problem is, you are requesting and processing data in each cell of your adapter. 问题是,您正在请求和处理适配器的每个单元中的数据。

try {
        holder.video_thum.setImageBitmap(retriveVideoFrameFromVideo(getItem(position).getURL()));
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }

that's the culprit. 那是元凶。 You are doing an expensive, non graphical task inside the main thread (the one managing the UI). 您正在主线程(管理UI的任务)内执行一项昂贵的非图形任务。 In order to optimize, you need to move that kind of operation to separate threads, and notify a class executing inside the main thread the results so it can update the UI. 为了进行优化,您需要将这种操作移到单独的线程中,并将结果通知给在主线程中执行的类,以便它可以更新UI。 There are several ways to do this: Asynctasks, Observers, Event buses. 有几种方法可以做到这一点:异步任务,观察者,事件总线。 For the sake of simplicity, let's go with an asynctask. 为了简单起见,让我们使用asynctask。

take this as an example: 以这个为例:

public class BitMapTask extends AsyncTask<Void, Void, Bitmap> {

public interface OnBitmapLoaded{
    void loadBitmap(Bitmap bitmap);
}

private OnBitmapLoaded bitmapLoaded;
private String url;

public BitMapTask(String url){
    this.url = url;
}

public BitMapTask setBitMapLoaded(OnBitmapLoaded bitMapLoaded){
    this.bitmapLoaded = bitMapLoaded;
    return this;
}

@Override
protected Bitmap doInBackground(Void... params) {
    return retriveVideoFrameFromVideo(url);
}

@Override
protected void onPostExecute(Bitmap result){
    if(bitmapLoaded != null) bitmapLoaded.loadBitmap(result);
}
}

then, instead of the try-catch, you should do something like this: 然后,您应该执行以下操作,而不是尝试捕获:

BitMapTask task = new BitMapTask(getItem(position).getURL())
                .setBitMapLoaded(new OnBitmapLoaded() {
            @Override
            public void loadBitmap(Bitmap bitmap) {
                if(bitmap != null){
                    setImageBitmap(bitmap);
                }
            }
        }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Keep in mind, this kind of operation will ignore the main thread status; 请记住,这种操作将忽略主线程状态; that means, the separate threads will keep running and executing even if the app is dormant, therefore, you need to void the listeners/unsubscribe receivers if the app goes to the foreground. 这意味着即使应用程序处于休眠状态,单独的线程也将继续运行并执行,因此,如果应用程序进入前台,则需要使侦听器/取消订阅接收器无效。 Happy coding. 快乐的编码。

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

相关问题 该应用程序可能在其主线程上做了大量工作(Android) - The application may be doing too much work on its main thread, (Android) 该应用程序可能在其主线程上做太多工作-Android - The application may be doing too much work on its main thread - Android Android-该应用程序可能在其主线程上做了大量工作 - Android - The application may be doing too much work on its main thread 在主线程中使用转换 animation 是应用程序可能在 android 的主线程上做太多工作的原因 - using transitions animation in main thread is the reason for The application may be doing too much work on its main thread in android 我的应用程序可能在其主线程上做过多的工作 - My application may be doing too much work on its main thread 该应用程序可能在其主线程上做过多的工作 - The application may be doing too much work on its main thread 应用程序可能在其主线程上做太多工作 - Application may be doing too much work on its main thread 应用程序可能在其主线程消息上做过多的工作 - the application may be doing too much work on its main thread message 片段:应用程序可能在其主线程上做太多工作 - Fragment: The application may be doing too much work on its main thread MapFragment-应用程序可能在其主线程上做过多的工作 - MapFragment - The application may be doing too much work on its main thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM