What will happen if I use try catch and finally fo

2019-04-16 10:55发布

问题:

I use the code below for getting some work done everytime after some time interval, and using post delay in 'finally' clause and oustide of runnable. Here is the code.

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                // do somthing
            } catch (Exception e) {
                // TODO: handle exception
            } finally {
                handler.postDelayed(this, 60000);
            }
        }
    };
    handler.postDelayed(runnable, 60000); 

handler.postDelayed(runnable, 60000); will run two times or a single time.

回答1:

it depends!

  • first matter

how the each try / catch / finally block completes normally or abruptly?

the finally block "always ^" executes when the try block exits

This ensures that the finally block is executed even if an unexpected exception occurs.

^ exception from above - finally may not be executed if jvm exits or thread gets killed

for details see java specs:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2

  • second matter

how Handler post/postDelayed method executes will pass? or fails? for some reason - for second this may happen if message was not placed in to the message queue - on failure, usually because the looper processing the message queue is exiting.

but most likely your statement will make a INFINITE loop

** ps. you need to throw an exception in try block or remove catch block (as try{} finally{} ) can exist "without" catch but code in catch block without rising any exception will make a compiler complain (code will not compile)

if you want loop n-times+1 you need to add some condition before postDelayed in Runnable run() method

in your case code flow execution:

  1. postDelayed method from last line outside definition of runnable
  2. execution of runnable by:
    • start of try block
    • with or without passing catch
    • through finally block with postDelayed in runnable run() method - wich will place runnable in message que for delayed execution on main thread
  3. then infinite loop on 2

so should i remove last postDelay out side of run() method to achieve postDelay run only ones in one loop. – AndroidMob

you can write this in such way:

    final Handler handler = new Handler();
    handler.post(new Runnable() {

        // this int will also be passed to method post delayed 
        // as "this" keyword applies to Anonymous Class 
        // which body contains everything between brackets of new Runnable() { ... }
        int withThis = 1;

        @Override
        public void run() {
            handler.postDelayed(this,1000);
        }
    });

so where should i call method to get done somthing ? in run() method..? – AndroidMob

this also depends what you want to achieve:

example

    handler.post(new Runnable() {

        int counter = 0;

        @Override
        public void run() {

            boolean wasPlacedInQue = false;

            doPreMethod();

            if(counter =< 10) { 
                  doMethod();
                  wasPlacedInQue = handler.postDelayed(this,1000);
            }

            if(wasPlacedInQue) { 
                  counter++; 
                  doPostyMethod(); 
            } else doFailureMethod();

        }

the code in run() method is executed synchronously on so called UI Thread - i'ts main thread which executes your application see:

https://developer.android.com/training/multiple-threads/communicate-ui.html

if you are interested to study it more I have made a full working example for you:

https://gist.github.com/c3ph3us/7d237d540e60597369856cb1fa652a23



回答2:

it surely will run two times. Because they are two different messages and handler will handle them separately.