Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is AsyncTask working on the main thread?

I'm trying to use AsyncTask to do a task in the background and then present it when it is done, but what happens is that nothing is displayed until it is done.

I also tried to use execute and doInBackground to call it, but both cause the same issue and I have to wait for the activity to start with everything ready rather than show a page with the loading progress bar and then add the list later.

Code:

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();
        }
    }
}
like image 740
newbieandroid Avatar asked May 09 '18 11:05

newbieandroid


People also ask

Does Async task run on main thread?

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.

What is the primary reason to use the doInBackground method of an AsyncTask?

doInBackground(Params) − In this method we have to do background operation on background thread. Operations in this method should not touch on any mainthread activities or fragments. onProgressUpdate(Progress…) − While doing background operation, if you want to update some information on UI, we can use this method.

What are the problems in AsyncTask?

In summary, the three most common issues with AsyncTask are: Memory leaks. Cancellation of background work. Computational cost.

What is the replacement of AsyncTask?

AsyncTask is used to perform time talking operations in android, but it's marked as deprecated from android 11. There are many alternatives are available for replacing an AsyncTask, one of the replacements is ExecutorService.

What is the difference between AsyncTask and thread?

Thread can be triggered from any thread, main(UI) or background; but AsyncTask must be triggered from main thread. Also on lower API of Android(not sure, maybe API level < 11), one instance of AsyncTask can be executed only once.

Which methods are run on the main UI thread AsyncTask?

onPreExecute: This is the first method that runs when an asyncTask is executed. After this, doInBackground is executed. This method runs on the UI thread and is mainly used for instantiating the UI.


1 Answers

If you want to show something in the UI while the AsyncTask is computing the background task you should implement the onProgressUpdate(Progress... values) method which is called from publishProgress(Progress... values) and implements the logic under the background task progress. In your code you just show the final result in the onPostExecute(). Note that the AsyncTask run the doInBackground() method in a different thread than the UI thread and onProgressUpdate() and onPostExecute() on the UI thread because they should update UI. For more info refer to the Android Doc about AsyncTask.

like image 174
simo-r Avatar answered Oct 14 '22 00:10

simo-r