0

The following code is what I'm using currently, but there is an issue that the Toast is being shown, so it probably is in the UI thread isn't it? I do not want the run() function to run on the UI thread as I will probably add some heavy downloading there. However, I want to repeatedly execute this code (after every 9000ms) So what must I do, to either make this run off the UI thread, or a solution to my problem. Thank you.

    final Handler handler = new Handler();
    Thread feedthread = new Thread()
    {
        @Override
        public void run() {
            super.run();
            Toast.makeText(context, "UI", Toast.LENGTH_SHORT).show();
            handler.postDelayed(this, 9000);
        }
    };
    handler.postDelayed(feedthread, 9000);

Please do not suggest AsyncTask to me unless there is a way to repeat the code without using a while loop wasting resources or setting the thread to sleep. I would like answers to what I asked, and I do not want to run the code on the UI thread.

A B
  • 189
  • 2
  • 9
  • You can use AsyncTask instead of Thread, it has callbacks for this UI stuff. – ElDuderino Dec 05 '15 at 18:07
  • why do you call `postDelayed` with a `Thread` object ? – pskink Dec 05 '15 at 18:43
  • I want to run the runnable at a later time, and I want it to run asynchronously, hence I delayed the post of a new thread. If this is the wrong way, please help me on which is right. I would prefer not to use async tasks or setting the thread to sleep – A B Dec 07 '15 at 05:35

3 Answers3

0

You need to call the runOnUiThread method to show the Toast

final Handler handler = new Handler();
Thread feedthread = new Thread()
{
    @Override
    public void run() {
        super.run();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, "UI", Toast.LENGTH_SHORT).show();
            }
        });
        handler.postDelayed(this, 9000);
    }
};
handler.postDelayed(feedthread, 9000);
Vasileios Pallas
  • 4,801
  • 4
  • 33
  • 50
  • I DON'T want to show the toast, I don't want the code to run on the UI thread, and the toast was just to check if it does. – A B Dec 05 '15 at 18:10
0

You want to use the AsyncTask class. Here is an example to show how it works:

// Async Task Class
private class MyTask extends AsyncTask<String, String, String> {

    // (Optional) Runs on the UI thread before the background task starts
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Do some UI stuff if needed
    }

    // Runs on a background thread
    @Override
    protected String doInBackground(String... param) {
        String url = param[0];
        // Do something with the param, like kick off a download
        // You can also use publishProgress() here if desired at regular intervals
        /*while (isDownloading) {
            publishProgress("" + progress);
        }*/
        return null;
    }

    // (Optional) Runs on the UI thread periodically during the background task via publishProgress()
    protected void onProgressUpdate(String... progress) {
        // Update UI to show progress
        /* prgDialog.setProgress(Integer.parseInt(progress[0])); */
    }

    // (Optional) Runs on the UI thread after the background task completes
    @Override
    protected void onPostExecute(String file_url) {
        // Do some UI stuff to show completion of the task (if needed)
    }
}

You can run your task like this:

String url = getInternetUrl();
new MyTask().execute(url);
mikejonesguy
  • 9,779
  • 2
  • 35
  • 49
0

Java Thread

new Thread(new Runnable(){
    private boolean stopped = false;

    @Override
    public void run(){
        while(!stopped) {    
            // Do, do, do...
            try {
                Thread.Sleep(9000);
            } catch(Exception e){}
        }
    }
}).start();

Android Handler

Also you can use Android handler class to run a code periodically. This requires you to have a looper-prepared thread to attach the handler to. Basically, a looper-prepared thread is assign a queue and every message posted to this thread will be queued and processed one by one in a queue manner.

This approach has a difference with the former one and is that if your do a lot of work in that background thread so that takes some time, then subsequent queued messages will be processed quicker than the interval (in this case, 9 seconds). Because looper-enabled threads immediately process the next queued message, once they are done with the previous one.

Find More Info Here


Note: You shouldn't [and can't] use this approach as an alternative to Service. This newly created thread does need an underlying component (either Activity or Service) to keep it alive.

Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • All I was advised is, to not use Thread.sleep and instead use postdelayed as thread sleep keeps the resources alive until it wakes up again, I don't know properly. But if there is a disadvantage to thread.sleep, please could you edit the code to have delayed post by a handler? – A B Dec 07 '15 at 05:34