OnCreate方法不断被重复调用

时间:2013-01-16 05:58:23

标签: android oncreate


更新:谢谢大家帮我解决这个问题。我仍然不确定原因,我能够回滚到之前的提交并从那里继续开发。之前的提交确实显示了相同的错误,但是在我评论button.performClick()之后它就消失了。奇怪的是,这不适用于最近的提交。

我仍然不明白这个错误,并希望在帮助确定根本原因方面提供更多帮助。我最担心的是无意中重新介绍它。


我有一个我见过的最疯狂的错误。

一遍又一遍地调用OnCreate方法,冻结我的应用程序并给我一点点闪烁。然后唯一的解决方案是退出到主屏幕并强制从设置菜单退出应用程序。

以下是详细情况:

  1. 申请开始(主要活动)
  2. 主要活动调用第二个活动
  3. 第二个活动调用onCreate,设置为正常
  4. 第二个活动随机决定退出onCreate< - 我想这就是发生了什么
  5. 第二个活动的onCreate再次被调用。它永远不会返回主要活动。
  6. 我运行了一个调试器,看来第二个活动成功完成onComplete / onResume序列,然后决定退出并重启。

    以前有没有人听说过这种行为?

    我没有注意到任何异常被抛出。此外,在调试过程中,我确实继续检查那些您认为是静默失败的位置。 (这是我用打印语句乱丢之前的旧代码)

    更新:尝试停止此过程时,我必须打开飞行模式。这意味着它与此代码块(第二个活动)

    有关
    else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId())
            {...}
    

    如果没有互联网,它会点击else语句,但不会显示此行为。

    CODE:

    主要活动的onResume(),我调用第二个活动:

        @Override
        public void onResume()
        {
            super.onResume();
    
            //Check If logged in, else go to login page
            Login.setContext(getApplicationContext());
    
            //Reset Notification Number
            GCMIntentService.cancelNotifications();
    
            /** GO TO LOGIN **/
            if(!Login.isLoggedIn())
            {
                //If user is not logged in, open login page
                System.out.println("RESUMING MAIN AND STARTING LOGIN INTENT");
                Intent intent = new Intent(ActivityMain.this, ActivityLogin.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
    
            } else
            {
                Login.setupStuffOnce();
                Event.pullEvents(); //Get New Events
    
                //Update ListView
                updateMainFeed();
            }
    
    
        }
    

    这是第二项活动:

    public class ActivityLogin extends Activity
    {
    
        private String postData;
        //private Context c;
        //final Timer timer = new Timer();
    
        //Facebook Stuff
        private Facebook facebook = new Facebook(Config.FBAPPID);
        private AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
    
        //Layout Stuff
        EditText username, password;
        Button loginButton, signupButton;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            // Open Database
            Login.setContext(getApplicationContext());
            Database.open(getApplicationContext());
        }
    
        /*
         * @Override public void onPause() { s }
         */
        @Override
        public void onResume()
        {
            super.onResume();
    
            // shouldn't put here but oh well
            init();
    
            //If coming from ActivitySignup
            if(Transfer.username != null)
            {
                username.setText(Transfer.username);
                password.setText(Transfer.password);
                Transfer.password = null;
                Transfer.username = null;
                loginButton.performClick();
            }
    
        }
    
        public void init()
        {
    
            Login.getUserLoggedIn();
            if (Login.isLoggedIn())
            {
                //Do Any Additional Setup
                Login.setupStuffOnce();
    
                // If user is logged in, open main
                Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
                //intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
    
            } else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId())
            {
                // Else, Make User Login
                // Inflate Login and Present Website
                String clientid = Login.getClientId();
                System.out.println("clientid:" + clientid);
                //System.exit(0);
                postData =  "mobile=1&client_id="+Login.getClientId();
    
    
    
                // Inflate the view
                setContentView(R.layout.activitylogin3);
    
                username = (EditText) findViewById(R.id.username);
                password = (EditText) findViewById(R.id.password);
    
    
    
                //Inflate the Button
                loginButton = (Button) findViewById(R.id.loginButton);
                signupButton = (Button) findViewById(R.id.signupButton);
    
                signupButton.setOnClickListener(new View.OnClickListener()
                {
    
                    @Override
                    public void onClick(View v)
                    {
                        Intent intent = new Intent(ActivityLogin.this, ActivitySignup.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
                        startActivity(intent);
    
                    }
                });
    
                loginButton.setOnClickListener(new View.OnClickListener() {
                      public void onClick(View view) {
    
                         int res = Login.sendLogin(username.getText().toString(), password.getText().toString());
    
                         if(res == 202)
                         {
                             //Login Successful
    
                             //Check if facebooked.
                             if(Login.isFacebooked())
                             {
                                 //Just go to main
                                 Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
                                 //Are these flags necessary?
                                 //intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                                 startActivity(intent);
                             } else
                             {
                                 //Go to facebook login page
                                 //Intent intent = new Intent(ActivityLogin.this, ActivityFBLogin.class);
                                 //startActivity(intent);
    
                                 //Login via Facebook
                                 doFacebook();
                             }
    
                         } else
                         {
                             System.out.println("Login Failed: "+res);
                             if(res == 405)
                             {
                                 Toast.makeText(getApplicationContext(), "Incorrect Username/Password", Toast.LENGTH_SHORT).show();
                                 password.setText("");
                             }
                             else
                                 Toast.makeText(getApplicationContext(), "Network Error", Toast.LENGTH_SHORT).show(); //Not entirely true in all cases i think
    
                         }
    
    
    
                          /*Login.getUserLoggedIn();
                            if(Login.isLoggedIn())
                            {
                                Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
                                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(intent);
                            } else {
                                Toast.makeText(getApplicationContext(), "Please Login Above", Toast.LENGTH_SHORT).show();
                            }*/
                      }
                    });
    
    
    
            } else
            {
                // Not Logged In and No Internet Access
    
                setContentView(R.layout.activitylogintext);
    
                EditText text = (EditText) findViewById(R.id.text);
                text.setText("No Internet Connection Detected\n requires internet to login");
    
                Button button = (Button) findViewById(R.id.refreshButton);
    
                button.setOnClickListener(new View.OnClickListener() {
                      public void onClick(View view) {
                            //Login.getUserLoggedIn();
                            if(Network.haveNetworkConnection(Login.getContext()))
                            {
                                Intent intent = new Intent(ActivityLogin.this, ActivityLogin.class);
                                //intent.setFlags();
                                startActivity(intent);
                            } else {
                                Toast.makeText(getApplicationContext(), "No Internet Access Detected", Toast.LENGTH_SHORT).show();
                            }
                      }
                    });
    
            }
    
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            facebook.authorizeCallback(requestCode, resultCode, data);
        }
    
        public void doFacebook()
        {
             facebook.authorize(this, Config.facebookPermissions, new DialogListener() {
                    @Override
                    public void onComplete(Bundle values) {
                         /*SharedPreferences.Editor editor = state.edit();
                         editor.putString("access_token", facebook.getAccessToken());
                         editor.putLong("access_expires", facebook.getAccessExpires());
                         editor.commit();
                            */
                         //Input into database
                         Login.saveAccessToken(facebook.getAccessToken());
                         Login.setFB(facebook.getAccessToken());
                         //Login.sendAccessToken(facebook.getAccessToken());
    
                         //Intent into Main Activity
                         Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
                        //intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
    
                    @Override
                    public void onFacebookError(FacebookError error) {
                        Toast.makeText(getApplicationContext(), "Error: "+error.getErrorType(), Toast.LENGTH_SHORT).show();
                    }
    
                    @Override
                    public void onError(DialogError e) {
                        Toast.makeText(getApplicationContext(), "Error: "+e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
    
                    @Override
                    public void onCancel() {}
                });
        }
    
        public boolean checkForUserID(Context c)
        {
            try{
                String res = Network.getUrl("www.website.com/mobile.php?got_user=1&client_id="+Login.getClientId());
                JSONObject json = JSON.constructObject(res);
                if(JSON.handleCode(json))
                {
                    if(json.getString("type").equals("userid"))
                    {
                        Login.setLogin(json.getString("data"));
                        return true;
                    }
                }
            } catch(Exception e)
            {
                //Silent Fail
            }
            return false;
        }
    
    
    }
    

6 个答案:

答案 0 :(得分:5)

我相信如果您在致电MainActivity后完成SecondActivity,问题就会得到解决。问题可能是当您恢复onResume时会立即触发MainActivity事件。这是因为MainActivity可能在背景中被破坏并重新创建。另一种解决方案是使用onSaveInstanceState保存您的活动状态。有关详细信息,请参阅here

答案 1 :(得分:4)

在您的活动中查看此代码:

    Button button = (Button) findViewById(R.id.refreshButton);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {

                    if(Network.haveNetworkConnection(Login.getContext()))
                    {
                        Intent intent = new Intent(ActivityLogin.this, ActivityLogin.class);
                        //intent.setFlags();
                        startActivity(intent);
                    } else {
                        Toast.makeText(getApplicationContext(), "No Internet Access Detected", Toast.LENGTH_SHORT).show();
                    }
              }
            });

您在这里调用ActivityLogin。 这就是为什么onCreate()被一次又一次地调用。

答案 2 :(得分:2)

我曾遇到过类似的问题。出现此问题是因为我在android:configChanges标记的<activity>属性中进行了配置更改而没有声明它们(因此它会在整个时间内重新创建)。

例如,如果您手动更改区域设置,则需要将locale添加到android:configChanges

答案 3 :(得分:2)

我认为你的主要问题是你的onResume函数,因为它每次回到视图时都被调用(例如:你开始第二个活动,完成它,再次调用主活动onResume。如果你完成了第二个活动(或者它会因某种原因而悄然崩溃)你会回到你的mainActivity并调用onResume(它会重新开始循环)。

现在我不知道你是否以某种方式完成了活动2,但我会检查一下。

编辑: 我也会在这里放一些logcats

if (Login.isLoggedIn())
{
      //Do Any Additional Setup
      Login.setupStuffOnce();

      // If user is logged in, open main
      Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
      //intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
      Log.i("Some Tag", "Starting Main Activity From Activity 2");
      startActivity(intent);

}

上面添加的log.i将让您知道这是否发生错误,您可以从那里开始。

答案 4 :(得分:2)

在我看来,如果Login未在活动之间正确分享,导致Login.isLoggedIn()true中返回ActivityLogin,则很有可能无休止地骑自行车false中的ActivityMain

一些关键因素是您的Login对象所在的位置,是静态的,它是如何在活动之间引用的?当ActivityLogin处于活动状态时,ActivityMain完全被销毁;将登录数据存储在SharedPreferences或数据库中,或以其他方式保存它很重要。 isLoggedIn()如何解决(确定其return值?)

建议1:考虑使用Singleton模式(如果你还没有。) 建议2:虽然不鼓励,但您可以将Login存储在Application级别。 建议3:您可以尝试使用Intent.FLAG_ACTIVITY_SINGLE_TOP来减少正在创建的新ActivityMain的可能性 - 这可能无法访问Login,这取决于您如何存储它。

ActivityMain

onResume() {
    if(!Login.isLoggedIn()) {
        /* Not logged in, launch ActivityLogin! */
        Intent intent = new Intent(ActivityMain.this, ActivityLogin.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

ActivityLogin

onResume() { /* ... */ init(); }

init() {
    Login.getUserLoggedIn();
    if (Login.isLoggedIn()) {
        /* Internet - launch ActivityMain! */
        Intent intent = new Intent(ActivityLogin.this, ActivityMain.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // <--- suggested addition
        startActivity(intent);
    else if (Network.haveNetworkConnection(Login.getContext()) && Login.checkClientId()) {
        /* No internet, the user was unable to login. */
    }

答案 5 :(得分:0)

我有类似的问题,其中活动将一直重建。重新安装应用程序无济于事,但重新启动手机完成了这项工作。