Results 1 to 13 of 13
  1. #1
    StateMachine is offline Member
    Join Date
    Dec 2011
    Posts
    22
    Rep Power
    0

    Question Explanation of nested methods as argument (Android)

    I would like to understand what's happening in some typical java code for Android. It's nested and nasty, I think:

    1) The method menuList.setOnItemClickListener is called and the rest of the code is an argument to that method. Right?

    2) The argument begins with declaring (overriding?) a new method called AdapterView.OnItemClickListener(). And the rest of the code are the statements of this method. Is that right???

    3) This method in turn declares another method named onItemClick() with some parameters after which the rest of the code is this method (mostly a set of if statements). Right?

    I really need help to understand why things are done this way. Why are new methods nested in each other as an argument to a third method? Is that a particular design pattern or something? The code is from page 135-136 of "Sams Teach yourself Android in 24 hours", but similar code seems to be common.

    Java Code:
    menuList.setOnItemClickListener(
       new AdapterView.OnItemClickListener() {
       public void onItemClick(AdapterView<?> parent, View itemClicked,
          int position, long id) {
          TextView textView = (TextView) itemClicked;
          String strText = textView.getText().toString();
          if (strText.equalsIgnoreCase(getResources().getString(
                R.string.menu_item_play))) {
             // Launch the Game Activity
             startActivity(new Intent(QuizMenuActivity.this,
                   QuizGameActivity.class));
                   } else if
    // Snip: And so on.
             }
    }
    Thank you!:
    Last edited by StateMachine; 01-03-2012 at 04:51 AM.

  2. #2
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    6

    Default Re: Explanation of nested methods as argument (Android)

    1) The method menuList.setOnItemClickListener is called and the rest of the code is an argument to that method. Right?
    Kind of, what you're seeing is anonymous inner class definition. It's when you define the body of the class anonymously inside a param block. This kind of speaks to the rest of your questions.

    2) The argument begins with declaring (overriding?) a new method called AdapterView.OnItemClickListener().
    Could also be implementing - as this works with subclasses and interfaces.

    And the rest of the code are the statements of this method. Is that right???
    Not quite, they are statements and methods inside this anonymous inner class.

    3) This method in turn declares another method named onItemClick() with some parameters after which the rest of the code is this method (mostly a set of if statements). Right?
    More or less. You don't have to write it this way, you can also write this formally with named variables and subclasses. I think the following would be more or less equivalent:

    Java Code:
    public void SomeMethod(){
        MyClickListener myClickListener = new MyClickListener();
        menuList.setOnItemClickListener(myClickListener);
    }
    
    class MyClickListener extends AdapterView.OnItemClickListener{
        public void onItemClick(AdapterView<?> parent, View itemClicked, int position, long id) {
            TextView textView = (TextView) itemClicked;
            String strText = textView.getText().toString();
            if (strText.equalsIgnoreCase(getResources().getString(R.string.menu_item_play))) {
                startActivity(new Intent(QuizMenuActivity.this, QuizGameActivity.class));
            } else if(someConditional){
                // Snip: And so on.
            }
        }
    }

  3. #3
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Explanation of nested methods as argument (Android)

    1) The method menuList.setOnItemClickListener is called and the rest of the code is an argument to that method. Right?
    Yes. The rest of the code is describing what will happen when an item click occurs.

    2) The argument begins with declaring (overriding?) a new method called AdapterView.OnItemClickListener(). And the rest of the code are the statements of this method. Is that right???
    Not quite. That's not a method, but a simple use of "new" to create an instance of a class: in this case an instance of AdapterView.OnItemClickListener. The setOnItemClickListener() method expects an instance of this type and that is what is being passed.

    What is slightly subtle here is that a new type is being defined. It is a subtype of AdapterView.OnItemClickListener and it does not have a name. It is an "anonymous class."

    3) This method in turn declares another method named onItemClick() with some parameters after which the rest of the code is this method (mostly a set of if statements). Right?
    Yes (except that it's a class definition, not a method) another method onItemClick() is being declared - almost certainly in this case it is overriding the method which will have been declared in the parent type.

    Sorry to keep talking about "types" here, but this sort of code arises in connection with both classes and interfaces. Commonly it is interfaces that are involved.

    They are OK if very brief but can become very tiresome if the code is long - or there are multiple of them one for each of a number of arguments. Compare:

    Java Code:
    interface SomeInterface {
        void foo();
    }
    
    class SomeClass {
        void bar(SomeInterface baz) {
            // ...
        }
    
        void method() {
            bar(new SomeInterface() {
                    @Override
                     public void foo() {
                         // code here
                     }
                });
        }
    }
    with the equivalent

    Java Code:
    interface SomeInterface {
        void foo();
    }
    
    class SomeClass {
        void bar(SomeInterface baz) {
            // ...
        }
    
        void method() {
            SomeInterface baz = new SomeInterface() {
                @Override
                 public void foo() {
                     // code here
                 }
            };
            bar(baz);
        }
    }
    or the - less expressive because "// code here" can't use final variables in method:

    Java Code:
    interface SomeInterface {
        void foo();
    }
    
    class SomeClass {
        void bar(SomeInterface baz) {
            // ...
        }
    
        private SomeInterface myBaz = new SomeInterface() {
            @Override
            public void foo() {
                // code here
            }
        };
    
        void method() {
            bar(myBaz);
        }
    }
    Personally I think the less indentation, the better.

    Roedy Green discusses anonymous classes here and gives another alternative: a named class that implements SomeInterface. His page on nested classes might also be useful as anonymous class are a sort of nested class.

  4. #4
    StateMachine is offline Member
    Join Date
    Dec 2011
    Posts
    22
    Rep Power
    0

    Default Re: Explanation of nested methods as argument (Android)

    Thank you all!
    I'll look into anonymous inner classes, and see what I get out of it.

  5. #5
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    6

    Default Re: Explanation of nested methods as argument (Android)

    Yeah, really not much too it, the anonymous part just means you don't name it i.e.
    instead of:
    Java Code:
    String name = new String("bob");
    System.out.println(name);
    'bob' is anonymous if you do this:
    Java Code:
    System.out.println(new String("bob"));
    And the 'inner' part just means you're defining the guts on the fly:
    Java Code:
    ActionListener ralph = new ActionListener(){
        public void ActionPerformed(ActionEvent ae){
            //Do Something
        }
    }
    Combine them, and you have an anonymous inner class! :D

  6. #6
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Explanation of nested methods as argument (Android)

    In fact I think the "anonymous" part refers to the fact that the type doesn't have a name. With new String("bob"), the type does have a name: String.

  7. #7
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    6

    Default Re: Explanation of nested methods as argument (Android)

    In fact I think the "anonymous" part refers to the fact that the type doesn't have a name. With new String("bob"), the type does have a name: String.
    That makes sense for interface implementations, but what about the String example? Isn't that still anonymous instantiation?

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Explanation of nested methods as argument (Android)

    The relevant bit of the JLS is 15.9 Class Instance Creation Expressions where the concept of an anonymous class is defined near the end: "Both unqualified and qualified class instance creation expressions may optionally end with a class body. Such a class instance creation expression declares an anonymous class (15.9.5) and creates an instance of it."

    Java Code:
    String name = new String("bob");
    System.out.println(name);
    
    System.out.println(new String("bob"));
    
    int answer = 6 * 7;
    System.out.println(answer);
    
    System.out.println(6 * 7);
    new String("bob") behaves for all the world like 6 * 7. There is no implicit type definition going on, rather it's just a class instance creation expression rather than a multiplicative arithmetic expression and can be used as part of an assignment or a method call.

    I can well understand that you might say to someone whose method call involves a line several hundred characters long with expressions that might throw all sorts of exceptions when they are evaluated, "don't you think it would be a good idea not to use those expressions "anonymously" like that?". But the point is that this usage is not what the JLS defines in Ch 15.

    I didn't want to belabour the point. (although I realise I have!) It's just that this matter has some bearing on method call semantics being discussed elsewhere here. The arguments in a method call are always expressions. It's true we can use variables, but that might be a little deceptive because the method doesn't "get" the variable in any real sense. Rather the variable is an expression (better, perhaps, the expression consists of the variable) which is evaluated like any other and the resulting value is what the method gets.
    Last edited by pbrockway2; 01-04-2012 at 01:07 AM.

  9. #9
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    6

    Default Re: Explanation of nested methods as argument (Android)

    No, that's a great point. I studied compiler design, so I understand where you're going, semantics are very important especially when trying to communicate :) Thanks for the info!

  10. #10
    bdtuhin007 is offline Member
    Join Date
    Oct 2011
    Posts
    5
    Rep Power
    0

    Default Re: Explanation of nested methods as argument (Android)

    hi all,

    I have a code but it doesn't work ! can you please help me on it? it will show graph in android field. but startActivity doesn't properly !! can anyone help me please ?

    <<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>

    int DataCnt = 6;
    SortedData[][] //This is an 2D array
    ---------------
    [[FASTWEB-2012, -66, 0], [FASTWEB-1-001CA2B8E818, -85, 0], [FASTWEB-2012, -66, 5], [FASTWEB-1-001CA2B8E818, -85, 5], [FASTWEB-2012, -66, 10], [FASTWEB-1-001CA2B8E818, -85, 10]]
    TerminalCount[][] ////This is an 2D array
    -------------------
    [[FASTWEB-2012, 3], [FASTWEB-1-001CA2B8E818, 3]]


    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

    switch (TermDimenSnRow) //suppose I have TermDimenSnRow = 2
    {
    case 1:
    break;

    case 2:
    TimeSeries series2 = new TimeSeries("WiFi 1");
    TimeSeries series3 = new TimeSeries("WiFi 2");
    for( int i2 = 0; i2 < DataCnt; i2++)
    {
    if(TerminalCount[0][0].equals(SortedData[i2][0]))
    {
    int WifiRSSIVal = (Integer.parseInt(String.valueOf(SortedData[i2][1])));
    int WifiTimeVal = (Integer.parseInt(String.valueOf(SortedData[i2][2])));
    series2.add(WifiRSSIVal, WifiTimeVal);
    }
    }
    for( int i3 = 0; i3 < DataCnt; i3++)
    {
    if(TerminalCount[1][0].equals(SortedData[i3][0]))
    {
    int WifiRSSIVal = (Integer.parseInt(String.valueOf(SortedData[i3][1])));
    int WifiTimeVal = (Integer.parseInt(String.valueOf(SortedData[i3][2])));
    series3.add(WifiRSSIVal, WifiTimeVal);
    }
    }
    dataset.addSeries(series2);
    XYSeriesRenderer renderer2 = new XYSeriesRenderer();
    mRenderer.addSeriesRenderer(renderer2);

    dataset.addSeries(series3);
    XYSeriesRenderer renderer3 = new XYSeriesRenderer();
    mRenderer.addSeriesRenderer(renderer3);
    break;
    case 3:
    break;
    -
    -
    -
    -
    -


    case 10:
    break;

    Intent intent = ChartFactory.getLineChartIntent(context, dataset, mRenderer, "Graph 1");
    this.startActivity(intent); //I have tried here by this (startActivity(intent))
    <<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>

  11. #11
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Explanation of nested methods as argument (Android)

    @bdtuhin007

    Please start a thread for your question.

  12. #12
    bdtuhin007 is offline Member
    Join Date
    Oct 2011
    Posts
    5
    Rep Power
    0

    Default Re: Explanation of nested methods as argument (Android)

    I can't find, from where I can start a new thread ! :(

  13. #13
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default Re: Explanation of nested methods as argument (Android)

    The process is much the same as you used when you cross posted at javaprogrammingforums.com

    Go to the Android forum and click on the button in the upper left corner that says "+Post New Thread".

    Please have the curtsey to let people know (both here, there, coderanch.com, ...) that you are cross posting. And bear in mind that many people will be reluctant to offer help if they are unaware of most of the discussion that is going on all over the internet.
    Last edited by pbrockway2; 01-17-2012 at 12:54 AM.

Similar Threads

  1. Replies: 1
    Last Post: 12-24-2011, 04:41 AM
  2. Replies: 10
    Last Post: 10-28-2011, 09:12 PM
  3. Replies: 20
    Last Post: 03-22-2011, 04:02 AM
  4. Explanation of Nested Loop (very strange)
    By Jonotron in forum New To Java
    Replies: 5
    Last Post: 01-09-2011, 02:54 AM
  5. need explanation
    By marie in forum New To Java
    Replies: 2
    Last Post: 03-21-2010, 03:35 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •