为什么AsyncTask在主线程上工作?

new*_*oid 10 java android android-asynctask

我正在尝试AsyncTask在后台执行任务,然后在完成后呈现它,但会发生的事情是在完成之前不会显示任何内容.

我也尝试使用execute并doInBackground调用它,但两者都会导致相同的问题,我必须等待活动开始准备好一切,而不是显示带有加载进度条的页面,然后再添加列表.

码:

private class listTask extends AsyncTask<Void,Void,Void> {
    @Override
    protected Void doInBackground(Void... voids) {
        recyclerview.setAdapter(new ItemAdapter(getInternalFileList()));
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        progressbar.setVisibility(View.GONE);
    }

    List<GalleryItem> getInternalFileList(){
        String path = getActivity().getFilesDir().toString();
        File directory = new File(path);
        File[] files = directory.listFiles();
        List<GalleryItem> galleryItems = new ArrayList<>();

        MainDBRepository repo = new MainDBRepository(getActivity());
        HashMap<String,GalleryItem> itemsMap = repo.getItemsMap();

        for(File file : files) {
            if(itemsMap.containsKey(file.getName()))
                galleryItems.add(itemsMap.get(file.getName()));
        }

        Collections.reverse(galleryItems);

        return galleryItems;
    }

    private class ItemHolder extends RecyclerView.ViewHolder {
        ImageView mItemImageView;

        ItemHolder(View itemView) {
            super(itemView);
            mItemImageView = (ImageView) itemView.findViewById(R.id.image_view);
        }

        public void bindBackgroundImage(Bitmap backgroundImage){
            mItemImageView.setImageBitmap(backgroundImage);
        }

        public void bindImageViewer(final String path){
            mItemImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = ImageViewerActivity.newIntent(getActivity(), path);
                    startActivity(intent);
                }
            });
        }
    }

    private class ItemAdapter extends RecyclerView.Adapter<ItemHolder> {
        private List<GalleryItem> galleryItems;

        ItemAdapter(List<GalleryItem> galleryItems) {
            galleryItems = galleryItems;
        }

        @NonNull
        @Override
        public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            View v = inflater.inflate(R.layout.gallery_item, viewGroup, false);
            return new ItemHolder(v);
        }

        @Override
        public void onBindViewHolder(@NonNull ItemHolder itemHolder, int position) {
            GalleryItem galleryItem = galleryitems.get(position);
            String path = getActivity().getFilesDir() + "/" + galleryItem.getID();
            File file = new File(path);
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            itemHolder.bindBackgroundImage(bitmap);
            itemHolder.bindImageViewer(path);
        }

        @Override
        public int getItemCount() {
            return galleryitems.size();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

sim*_*o-r 9

如果要在AsyncTask计算后台任务时在UI中显示某些内容,则应实现onProgressUpdate(Progress ... values)方法,该方法publishProgress(Progress... values)在后台任务进度下调用并实现逻辑.在您的代码中,您只需显示最终结果onPostExecute().需要注意的是AsyncTask运行doInBackground()在不同的线程比UI线程和方法onProgressUpdate(),并onPostExecute()在UI线程,因为他们应该更新UI.有关更多信息,请参阅有关AsyncTask的Android Doc .

  • 片段有自己的生命周期,所以你只需要实现他们的`onSomething()`方法来正确加载UI部分.当你必须在后台执行"沉重"(花费大量时间)的事情时,使用"AsyncTask",避免UI冻结(不响应用户输入).我不认为使用`AsyncTask`是解决问题的正确方法. (3认同)

lig*_*igi 5

在背景上只是意味着 - 而不是在UI - 线程.要在作业完成之前获得结果,您需要在后台执行作业时将结果提供给UI线程.要在UI线程上获得结果,然后才能使用AsyncTask.onProgressUpdate(..) - 或者更好地使用kotlin协同程序而不是asynctask.