2017-08-20 7 views
1

私はアンドロイド開発に慣れていませんが、コード例を読み込もうとしているうちに、その中から呼び出されているメソッドが発生しました。論理的には、それ自体を呼び出す無限ループを作成する必要があります。しかし、それはしません。どうして?私MainActivity.javaなぜこのJava再帰メソッドは無限ループを作成していないのですか?

public void onWishlistSelected() { 
     launchUserSpecificFragment(new WishlistFragment(), WishlistFragment.class.getSimpleName(), new LoginDialogInterface() { 
      @Override 
      public void successfulLoginOrRegistration(User user) { 
       // If login was successful launch WishlistFragment. 
       onWishlistSelected(); // Why doesn't this create infine loop? 
      } 
     }); 
    } 

と、それを呼び出す:

public boolean onOptionsItemSelected(MenuItem item) { 

     int id = item.getItemId(); 

     if (id == R.id.action_wish_list) { 
      onWishlistSelected(); 
      return true; 
     } else if (id == R.id.action_cart) { 
      onCartSelected(); 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

EDIT

ここではlaunchUserSpecificFragment

private void launchUserSpecificFragment(Fragment fragment, String transactionTag, LoginDialogInterface loginListener) { 
     if (SettingsMy.getActiveUser() != null) { 
      replaceFragment(fragment, transactionTag); 
     } else { 
      DialogFragment loginDialogFragment = LoginDialogFragment.newInstance(loginListener); 
      loginDialogFragment.show(getSupportFragmentManager(), LoginDialogFragment.class.getSimpleName()); 
     } 
    } 
0123内のコードです

replaceFragment

private void replaceFragment(Fragment newFragment, String transactionTag) { 
     if (newFragment != null) { 
      FragmentManager frgManager = getSupportFragmentManager(); 
      FragmentTransaction fragmentTransaction = frgManager.beginTransaction(); 
      fragmentTransaction.setAllowOptimization(false); 
      fragmentTransaction.addToBackStack(transactionTag); 
      fragmentTransaction.replace(R.id.main_content_frame, newFragment).commit(); 
      frgManager.executePendingTransactions(); 
     } else { 
      Timber.e(new RuntimeException(), "Replace fragments with null newFragment parameter."); 
     } 
    } 

答えて

2

onWishlistSelected自体を呼び出すないので、無限再帰がここにありません。

LoginDialogInterfaceを実装する匿名クラスのインスタンスを引数として受け取るのは、launchUserSpecificFragmentです。

匿名クラスはonWishlistSelectedを呼び出すsuccessfulLoginOrRegistration方法が含まれていますが、onWishlistSelectedを呼び出すことは、必ずしもそのsuccessfulLoginOrRegistration方法を実行しません。 successfulLoginOrRegistrationが実行されるときは、launchUserSpecificFragmentのロジックに依存します。

+0

だから、 'successfulLoginOrRegistration'の中で呼び出されたとき、なぜ' launchUserSpecificFragment'をもう一度呼び出さないのですか? –

+0

@RameshPareek 'launchUserSpecificFragment'のコードを見て、それが何をしているのか見る必要があります。それ以外の場合は、それが何を呼び出すのか、それとも呼び出さないのかを伝える方法はありません。 – Eran

+1

@RameshPareekです。しかし、 'successfulLoginOrRegistration'は、少なくとも直ちには再び呼び出されません。 – Sweeper

0

このメソッドは、onWishlistSelectedメソッドを実行しているsuccessfulLoginOrRegistrationインターフェイスがあるため、決して無限に呼び出しません。要するに、onWishlistSelectedメソッドはinterfaceがコールバックをsuccessfulLoginOrRegistrationに取得した場合にのみ実行されます。あなたがonWishlistSelectedを呼び出す場所がonWishlistSelected方法自体に直接匿名クラス内ではなく

1

注意。

onWishlistSelectedへの呼び出しが、successfulLoginOrRegistrationというメソッドの中に置かれていることをよく確認してください。つまり、successfulLoginOrRegistrationが呼び出されたときにのみ、onWishlistSelectedが呼び出されます。

だからいつsuccessfulLoginOrRegistrationと呼ばれるのですか?私はあなたが与えたコードの量からこれを知ることができません。

ここでsuccessfulLoginOrRegistrationが呼び出されたとします。その結果、onWishlistSelectedが呼び出されますが、onWishlistSelectedは、次にsuccessfulLoginOrRegistrationが呼び出されたときにのみ呼び出されます。

ここで、「スタックトレースはこれらの2つのメソッド呼び出しで満たされないでしょうか?答えはおそらくそうではありません。コードの他の部分がsuccessfulLoginOrRegistrationを呼び出すことができるように、onWishlistSelectedが最初に返されます。したがって、スタックトレースはオーバーフローしません。

私はこれを説明する方が簡単に理解できる例を使用します。

private static JButton btn = new JButton("press me"); 
public static void main(String[]args) throws Exception { 
    JFrame frame = new JFrame(); 
    frame.add(btn); 
    someMethod(); 
    frame.setVisible(true); 
} 

public static void someMethod() { 
    btn.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("button pressed"); 
      someMethod(); 
     } 
    }); 
} 

これは無限ループを作成しません。 someMethodは、ユーザーがボタンを押したときにのみ実行されます。ユーザーがボタンを押すとactionPerformedが呼び出され、someMethodとなります。しかし、ユーザーがボタンを再びクリックするまで何も起こりません。

+0

もう少し詳しく説明します - ** OnwishSelectedはおそらく最初に返されます** 'ここで最初に意味することは?また、より関連性の高いコードで更新しました。 –

+0

'onWishlistSelected'が' _WirstlistSelected'を返すと、どこか他の場所から 'successfulLoginOrRegistration'が呼び出されます。(あなたが追加したコードからもわからないので、' successfulLoginOrRegistration'というメソッド呼び出しを見つける必要があります。 'successfulLoginOrRegistration'が呼ばれた後、' onWishlistSelected'が再び呼び出されます。 @RameshPareek – Sweeper

+0

@RameshPareek編集された答えを見てください。 – Sweeper

0

onWishListSelectedメソッドがそれ自身を呼び出すのではありません。それはsuccessfulLoginOrRegistrationメソッドを定義しますが、それを呼び出すことはありません。これはあなたが望むものです、私は信じています。

public void onWishlistSelected() { 
     boolean loginSuccess = false; 
     launchUserSpecificFragment(new WishlistFragment(), WishlistFragment.class.getSimpleName(), new LoginDialogInterface() { 
      @Override 
      public void successfulLoginOrRegistration(User user) { 
       // If login was successful launch WishlistFragment. 
      } 
      // set true when login successfully . 
      // loginSuccess = true; 
     }); 
     // call untill successfully logged in. 
     if(loginSuccess == false){ 
      onWishlistSelected(); 
     } 
}