I am new to android development, while trying to read a code example, I encountered a method which is being called from within itself, so logically it should create an infinite loop of calling itself. But it does not. why?
In my MainActivity.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?
}
});
}
and calling it:
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
Here is the code inside 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());
}
}
and 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.");
}
}
onWishlistSelected
is not calling itself, so there is not infinite recursion here.
It is calling launchUserSpecificFragment
, which receives an instance of an anonymous class implementing LoginDialogInterface
as an argument.
The anonymous class contains a successfulLoginOrRegistration
method that calls onWishlistSelected
, but calling onWishlistSelected
doesn't necessarily execute that successfulLoginOrRegistration
method. When successfulLoginOrRegistration
will be executed depends on the logic of launchUserSpecificFragment
.
Note that the place where you call onWishlistSelected
is inside an anonymous class and not directly in the onWishlistSelected
method itself.
If you look closely that your call to onWishlistSelected
is put inside a method called successfulLoginOrRegistration
. This means that only when successfulLoginOrRegistration
is called, onWishlistSelected
is called.
So when will successfulLoginOrRegistration
be called? I cannot know this from the amount of code you have given.
Now let's suppose that successfulLoginOrRegistration
is called. As a result, onWishlistSelected
is called, but then onWishlistSelected
will only be called the next time successfulLoginOrRegistration
is called.
Now you might ask, "Wouldn't the stack trace be filled with these two method calls?" The answer is probably not. onWishlistSelected
will probably return first, so that other parts of the code is able to call successfulLoginOrRegistration
. So the stack trace won't overflow.
I will use an easier-to-understand example to illustrate this:
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();
}
});
}
This will not create an infinite loop. someMethod
only executes when the user presses the button. When the user presses the button, actionPerformed
is called and so is someMethod
. But then nothing happens, until the user clicks the button again.
This method will never call infinitely reason is there is successfulLoginOrRegistration
interface which is executing your onWishlistSelected
method. In short your onWishlistSelected
method will execute only when your interface
will get callback in successfulLoginOrRegistration
.
onWishListSelected method is not calling itself. It defines a successfulLoginOrRegistration method but never calls it. This is what you want, I believe.
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();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.