LogoLogo
v7.0.0
v7.0.0
  • TotalCross Overview
  • TotalCross Javadoc
  • TotalCross Changelog
  • Roadmap
  • Documentation
    • Getting Started
      • First embedded project with TotalCross
    • Components
      • Accordion
      • Aligned Labels
      • Button
      • Check
      • ComboBox
      • Dynamic Scroll
      • Edit
      • Floating Button
      • Gpiod
      • Grid
      • GridContainer
      • Image
      • ImageControl
      • ImageList
      • Label
      • Material Icons
      • Material Window
      • MessageBox
      • Multi Edit
      • Progress Bar
      • Progress Box
      • Radio
      • Radio Group
      • Scroll Container
      • Side Menu
      • Slider
      • Sliding Window
      • Spin List
      • Spinner
      • Switch
      • Tabbed Container
      • Velocimeter
    • APIs
      • API Overview
      • API Rest
      • Asynchronous Task
      • Camera
      • Control
        • Main Window
        • Window
        • Container
      • GPS
      • HTTPS and SSL
      • JSON
      • Maps
        • Maps - Deprecated
        • Static Map
      • Material Design Standards
      • Ninepath
      • Notifications
      • PrinterManager
      • Push Notification Firebase
      • Scanner
      • SOAP
      • Socket
      • SocketServer
      • SQLite Encryption
      • QR Code Generator
      • totalcross.sys
      • Youtube API
    • Creating an Issue
    • Contributing
      • Branch workflow
      • Writing documentation
    • Guides
      • App Architecture
        • Suggested Architecture
        • Why do Design Patterns help with the application's organization?
          • MVC Architecture Pattern
          • Template Pattern
          • Data Persistence: DAO Pattern.
        • Separation of concepts: What is the best way to create UI interfaces?
        • Positioning
          • Manual Positioning
        • Relative Positioning
        • Best practices to improve project maintenance
      • Device Simulator
      • Package your app from scratch
        • TotalCross SDK
        • Environment Variables in IDE
          • Eclipse
          • IntelliJ
        • Deploy your app with a dependecy TC
        • Deploy iOS
          • Using Development certificate to test your apps
      • Understanding TotalCross for Linux ARM
      • Running C++ applications with TotalCross
      • Web Services
    • Miscelaneous
      • Java JDK 8
      • Maven
      • Installing Visual Studio Code
    • FAQ
      • IMEI in Android 10
Powered by GitBook
On this page

Was this helpful?

  1. Documentation
  2. APIs

Asynchronous Task

Executing background tasks in order to not lock the Main Thread.

PreviousAPI RestNextCamera

Last updated 5 years ago

Was this helpful?

Using AsyncTask class to execute background tasks

In order to execute task that can take a few seconds to be completely executed, one must run it apart from the main thread, i.e, the thread responsible for painting components. Executing this kind of task in the main thread may cause a non-good user experience, once the application user may be unable to use and see any progress while the task is being executed.

To avoid such an obstacle, TotalCross provides AsyncTask class, which is a helper to execute task in an asynchronous way. By using AsyncTask, the user can easily execute asynchronous task without complex manipulation of threads and, consequently, not locking the main thread. See the example bellow to learn how to use it.

Copy and paste this code inside a instance.

Button dldButton = new Button("download zip");
add(dldButton, CENTER, CENTER);

final ProgressBar progressBar = new ProgressBar();
add(progressBar, CENTER, AFTER + UnitsConverter.toPixels(DP + 16),
        PARENTSIZE + 80, PREFERRED);

dldButton.addPressListener((c) -> {
    new AsyncTask()<Void, Void, Void> {
        int progress = 0;
        UpdateListener updateListener = null;

        @Override
        protected Object doInBackground(Object... objects) {
            HttpStream.Options o = new HttpStream.Options();
            o.httpType = HttpStream.GET;
            final String url = "<INSERT AN URL TO DOWNLOAD A ZIP FILE>";

            if(url.startsWith("https:"))
                o.socketFactory = new SSLSocketFactory();

            try {
                HttpStream p = new HttpStream(new URI(url));
                File f = new File("file.zip", File.CREATE_EMPTY);
                int totalSize = p.contentLength;
                byte [] buff = new  byte[4096];
                BufferedStream bs = new BufferedStream(f, BufferedStream.WRITE, 4096);
                int counter = 0;
                while(true) {
                    int size = p.readBytes(buff, 0, buff.length);
                    counter += size;
                    progress = (int)((counter/(double)totalSize)*100);
                    if(size <= 0) break;
                    bs.writeBytes(buff, 0, size);
                }
                progress = 100;
                bs.close();
                p.close();
                f.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            dldButton.setEnabled(false);
            MainWindow.getMainWindow().addUpdateListener(updateListener = (elapsed) -> {
                progressBar.setValue(progress);
            });
        }

        @Override
        protected void onPostExecute(Object result) {
            dldButton.setEnabled(true);
            MainWindow.getMainWindow().removeUpdateListener(updateListener);
        }
    }.execute();
});

When the file is completely downloaded, the function onPostExecute is called removing the UpdateListener and reenabling the button dldButton.

Once method execute is called, before executing the asynchronous task, onPreExecute method is also called adding an UpdateListener to update the component in the adequate time interval trough the variable progress. The button dldButton is disabled to avoid user execute the same task many times unnecessarily.

Container
ProgressBar