3

I have a service which contains a Timer and TimerTask for receiving data from Webservice in periods of time. When my TimerTask runs, the UI hangs until the Webservice process complete. How can I put my task in a thread to prevent the UI hanging?

My code:

Timer timerSyncFull = new Timer();

class taskSyncFull extends TimerTask {
        @Override
        public void run() {
            hSyncFull.sendEmptyMessage(0);
        }
    };



final Handler hSyncFull = new Handler(new Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            procSyncFull();
            return false;
        }
    });

public void procSyncFull() {
        try {
            // My webservice process

        } catch (Exception e) {
        }
    }



@Override
    public void onStart(Intent intent, int startId) {

timerSyncFull = new Timer();

timerSyncFull.schedule(new taskSyncFull(), 5*60*1000,
                        5*60*1000);

}
Bob
  • 22,810
  • 38
  • 143
  • 225
  • Arey you trying to update UI from your service or doing some stuff that performs some action on the UI? – Lalit Poptani Jan 07 '12 at 09:25
  • no i do not do any stuff on UI. my service is separated from UI. – Bob Jan 07 '12 at 09:32
  • This is strange for me. because there should not be any relation between my activities and my services. Only my application hangs and other programs in OS works without hanging. – Bob Jan 07 '12 at 09:39

4 Answers4

1

Use AsyncTasks or attach your Handler to another Looper thread.

clemp6r
  • 3,665
  • 2
  • 26
  • 31
  • See the doc for sample code : http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html and http://developer.android.com/reference/android/os/AsyncTask.html – clemp6r Jan 07 '12 at 09:54
  • `final Runnable r = new Runnable() { public void run() { procSyncFull(); } }; final Handler hSyncFull = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { Utilities.performOnBackgroundThread(r); return false; } });` – Bob Jan 07 '12 at 10:13
  • 01-07 13:46:03.190: E/AndroidRuntime(4485): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() – Bob Jan 07 '12 at 10:15
  • A Handler can only be created on Looper threads (special threads that can manage Handlers). See the AsyncTask example which is simpler. – clemp6r Jan 07 '12 at 10:17
  • my proc has a Toast. the exception is for that. how can i call Toast in it. – Bob Jan 07 '12 at 10:28
  • The exception above has nothing to do with Toasts. It's raised because you're creating a Handler whithin a wrong Thread. – clemp6r Jan 07 '12 at 10:33
  • I tested it by `Log.i("aa", "aa");` and everything is OK now. But i can not show Toast there. how can i add toast in my code? – Bob Jan 07 '12 at 11:10
1

I used the following code and my problem solved:

class taskSendMapMovements extends TimerTask {
        @Override
        public void run() {
            hhSendMapMovements.sendEmptyMessage(0);
        }
    };



    // /////////////////////

    final Runnable rSendMapMovements = new Runnable()
    {
        public void run()
        {
            procSendMapMovements();
        }
    };

    final Handler hhSendMapMovements = new Handler(new Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            performOnBackgroundThread(rSendMapMovements);

            return false;
        }
    });

    // /////////////////////

    public void procSendMapMovements() {
        try {    

        showToast("some text");
        //My Main Process    

        } catch (Exception e) {


        }
    }


@Override
    public void onStart(Intent intent, int startId) {
        try {



            timerSendMapMovements = new Timer();


            timerSendMapMovements
                        .schedule(new taskSendMapMovements(),
                                10*60*1000,
                                10*60*1000);

            //

        } catch (NumberFormatException e) {
            Toast.makeText(this, "error running service: " + e.getMessage(),
                    Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Toast.makeText(this, "error running service: " + e.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }
    }


final Handler hToast = new Handler(new Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            Toast.makeText(SrvDataExchange.this,
                    msg.getData().getString("msg"),
                    Toast.LENGTH_LONG).show();
            return false;
        }
    });

private void showToast(String strMessage) {
    Message msg = new Message();
    Bundle b = new Bundle();
    b.putString("msg", strMessage);
    msg.setData(b);
    hToast.sendMessage(msg);
}

public static Thread performOnBackgroundThread(final Runnable runnable) {
        final Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } finally {

                }
            }
        };
        t.start();
        return t;
    }
Bob
  • 22,810
  • 38
  • 143
  • 225
0

Simply invoke your procSyncFull() method in thread or asyncTask.

final Handler hSyncFull = new Handler(new Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Thread thread=new Thread()
            {
                public void run(){
                    procSyncFull();

                }
            }
            return false;
        }
    });

private Handler webserviceCompletionHandler=new Handler()
{
    @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
};
jeet
  • 29,001
  • 6
  • 52
  • 53
0

use AsyncTask carry out your execution in doInBackground() and populate it in onPostExecute()

AsyncTask Example

Mukunda
  • 1,593
  • 3
  • 26
  • 45