我是Android开发的新手,在尝试阅读代码示例时,我遇到了一个从内部调用的方法,所以逻辑上它应该创建一个无限循环来调用自身。但事实并非如此。为什么呢?
在我的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?
}
});
}
并称之为:
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);
}
修改
以下是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());
}
}
和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.");
}
}
答案 0 :(得分:2)
onWishlistSelected
不调用自身,因此这里没有无限递归。
它正在调用launchUserSpecificFragment
,它接收一个实现LoginDialogInterface
作为参数的匿名类的实例。
匿名类包含调用successfulLoginOrRegistration
的{{1}}方法,但调用onWishlistSelected
并不一定会执行onWishlistSelected
方法。执行successfulLoginOrRegistration
时取决于successfulLoginOrRegistration
。
答案 1 :(得分:1)
请注意,您调用onWishlistSelected
的地方位于匿名类内,而不是直接位于onWishlistSelected
方法本身。
如果仔细观察,您对onWishlistSelected
的调用会被放入名为successfulLoginOrRegistration
的方法中。这意味着只有在调用successfulLoginOrRegistration
时,才会调用onWishlistSelected
。
那么什么时候会调用successfulLoginOrRegistration
?我从你给出的代码数量中无法知道这一点。
现在让我们假设successfulLoginOrRegistration
被调用。因此,系统会调用onWishlistSelected
,但只会在下次调用onWishlistSelected
时调用successfulLoginOrRegistration
。
现在您可能会问,"堆栈跟踪是否会被这两个方法调用填充?"答案可能不是。 onWishlistSelected
可能会先返回,以便代码的其他部分能够调用successfulLoginOrRegistration
。因此堆栈跟踪不会溢出。
我将使用一个更容易理解的例子来说明这一点:
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
也被调用。但是在用户再次点击按钮之前没有任何反应。
答案 2 :(得分:0)
此方法永远不会无限调用因为有successfulLoginOrRegistration
接口正在执行您的onWishlistSelected
方法。简而言之,只有当onWishlistSelected
在[{1}}中获得回调时,您的interface
方法才会执行。
答案 3 :(得分: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();
}
}