Почему AsyncTask работает в основном потоке? - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь использовать 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();
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Если вы хотите что-то показать в пользовательском интерфейсе, пока AsyncTask вычисляет фоновую задачу, вы должны реализовать метод onProgressUpdate (Progress ... values), который вызывается из publishProgress(Progress... values) и реализует логику в фоновой задаче. прогресс. В вашем коде вы просто показываете окончательный результат в onPostExecute(). Обратите внимание, что AsyncTask запускает метод doInBackground() в потоке, отличном от потока пользовательского интерфейса, и onProgressUpdate() и onPostExecute() в потоке пользовательского интерфейса, поскольку они должны обновлять пользовательский интерфейс. Для получения дополнительной информации обратитесь к Android Doc об AsyncTask .

0 голосов
/ 09 мая 2018

На фоне просто означает - не в пользовательском интерфейсе - поток. Чтобы получить результаты до завершения работы, вам нужно будет передать результаты в поток пользовательского интерфейса, выполняя работу в фоновом режиме. Чтобы получить результаты в потоке пользовательского интерфейса, прежде чем использовать AsyncTask.onProgressUpdate (..) - или лучше использовать сопрограммы kotlin вместо asynctask.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...