9

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

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


我遇到了我见过的最疯狂的错误。

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

以下是详细情况:

  1. 应用程序启动(主活动)
  2. 主活动调用第二个活动
  3. 第二个Activity调用onCreate,正常设置
  4. 第二个 Activity 随机决定退出 onCreate <--我认为这是发生了什么
  5. 第二个活动的 onCreate 再次被调用。它永远不会返回到主活动。

我已经运行了一个调试器,看来第二个活动成功完成了 onComplete/onResume 序列,然后决定退出并重新启动。

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

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

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

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

在没有互联网的情况下,它将命中 else 语句并且不显示此行为。

代码:

主活动的 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;
    }


}
4

6 回答 6

5

我相信,如果您MainActivity在致电后完成您的问题,问题将得到解决SecondActivity。问题可能是onResume当您恢复您的MainActivity. 那是因为它MainActivity可能在后台被销毁并重新创建。另一种解决方案是使用onSaveInstanceState. 请参阅此处了解更多信息。

于 2013-01-23T13:40:47.787 回答
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 本身。这就是为什么 theonCreate()被一次又一次地调用。

于 2013-01-16T06:14:48.260 回答
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 将让你知道这是否是错误发生的地方,你可以从那里开始。

于 2013-01-24T21:55:46.633 回答
2

我曾经遇到过类似的问题。出现问题是因为我进行了配置更改而没有在标签的android:configChanges属性中声明它们<activity>(因此它一直在重新创建自己)。

例如,如果您手动更改语言环境,则需要locale添加android:configChanges!

于 2013-01-24T18:10:22.997 回答
2

在我看来,如果Login活动之间没有正确共享,那么这里很有可能在这里进行无休止的骑行,导致Login.isLoggedIn()返回trueinActivityLoginfalsein ActivityMain

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

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

活动主

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);

活动登录

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. */
    }
于 2013-01-25T06:37:50.327 回答
0

我有类似的问题,活动将一直重新创建。重新安装该应用程序无济于事,但重新启动手机就可以了。

于 2013-11-07T07:03:29.700 回答