【问题标题】:Pressing back button from one activity refreshes previous activity in stack从一个活动按下后退按钮会刷新堆栈中的前一个活动
【发布时间】:2016-03-23 01:09:43
【问题描述】:

从子活动按后退按钮时,父活动会显示一秒钟并自行刷新。

在子活动中,我在 java 文件中有这段代码

@Override
public void onBackPressed()
{

    Intent moveback =
            new Intent(ClassActivityEdit.this, ClassActivity.class);
    startActivity(moveback);
    finish();
}

ClassActivityEdit 是子类。在manifest文件中代码如下

<activity android:name=".ClassActivity"
        android:label="Class Activity">
        <intent-filter>
            <action android:name="com.teamtreehouse.oslist.ClassActivity" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <activity android:name=".ClassActivityEdit"
        android:label="Class Activity"
        android:noHistory="true">
        <intent-filter>
            <action android:name="com.teamtreehouse.oslist.ClassActivityEdit" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

在返回按钮上,我只想显示 ClassActivity 布局而不刷新它。

编辑: ClassActivityEdit 不扩展 ClassActivity。只是在ClassActivity 中按下一些按钮将导致打开ClassActivityEdit

编辑2

ClassActivity 中的以下代码以 ClassActivityEdit 开头

public void editListener(View v) {
        Intent addNewClass =
                new Intent(ClassActivity.this, ClassActivityEdit.class);
        RelativeLayout buttonTableRow = (RelativeLayout) v.getParent();
        TextView getCourseID = (TextView) buttonTableRow.findViewById(R.id.courseNumberActivity);
        String courseIDString = getCourseID.getText().toString();
        Bundle bundle = new Bundle();

        //Add your data to bundle
        bundle.putString("CourseIDString", courseIDString);

        addNewClass.putExtras(bundle);
        startActivity(addNewClass);
}

编辑 3:我还有一个着陆 (MAIN) 活动,它会闪烁一秒钟。从ClassActivityEdit 活动按下返回按钮时,着陆活动再次闪烁,然后ClassActivity 活动加载。解决起来有点棘手。

public class LoadingPage extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loading_page);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent mainIntent = new Intent(LoadingPage.this, ClassActivity.class);
            startActivity(mainIntent);
        }
    }, 1000);
}

}

【问题讨论】:

  • 去掉onBackPressed()方法试试看
  • @ArpitPatel 不,它没有用
  • 你能提供更多代码吗?为什么你使用两个意图过滤器??
  • @ArpitPatel 添加了导致ClassActivityEdit的代码
  • 我认为这对你有帮助:) stackoverflow.com/questions/5545217/…

标签: android android-layout android-intent android-studio android-manifest


【解决方案1】:

你的问题太奇怪了!只需不覆盖 OnBackPressed,您将获得您想要的结果。 我想问题出在您的清单中。

android:noHistory="true"

它不会让活动留在历史堆栈中,请尝试将其删除。也试试这个:

android:launchMode="singleInstance"

通过这样做,活动不会再次被创建。

【讨论】:

  • 它不会被创建,但它仍然会调用 onNewIntent。然而,这只是在解决症状,而不是解决问题(存在请求实例的意图)
  • 亲爱的尼克,您能分享一下您的 LoadingPage 清单代码以及 LoadingPage 活动代码吗?用户按下后退按钮时,没有 ClassActivityEdit,因为您为其启用了 NOHISTORY,因此用户再次返回到 LoadingPage。如果再次创建加载页面,用户将再次被重定向到 ClassActivity。 @尼克卡多索
  • Edit 将是他离开的课程,但您似乎真的在猜测这些标志的作用。
【解决方案2】:

问题在于您对后按的覆盖(不需要覆盖),并且可能是焦点返回时您的活动所做的症状。

首先,如果您不覆盖onBackPress,则会加载前一个活动(这是默认行为,因为the backstack),因此您无需使用新意图手动调用它并告诉手动告诉它去上一个活动。

当您的父活动 (ClassActivity) 再次启动时,它将通过 normal lifecycle - 它将恢复并恢复所有已保存的实例状态。由于您尚未发布它,因此您需要确保 onResumeonRestart 在您的父活动中没有做任何事情,例如加载或设置数据。

如果您确实保留了您编写的onBackPress,那么它将创建一个新实例并且将始终调用onCreate,除非它被标记为singleInstance,在这种情况下将调用onNewIntent,但两者都不会这些东西似乎正是你想要的。

为了响应您的Edit 3,您需要确保 LoadingPage 具有 android:noHistory="true" 以使其对 backstack 不可用,然后 完成它明确在你启动主类时清理它

这很简单,就像在开始你的意图时调用 finish

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        Intent mainIntent = new Intent(LoadingPage.this, ClassActivity.class);
        startActivity(mainIntent);
        finish(); //end the wrapping activity (LoadingPage)
    }
}, 1000);

您应该注意的最后一件事是向上和向后导航之间的区别。如果您通过主页/向上按钮导航回来,您还应该告诉清单这两个活动是相关的。在 ClassActivityEdit 的清单条目中,您应该添加 android:parentActivityName="com.teamtreehouse.oslist.ClassActivity"

【讨论】:

    【解决方案3】:

    只需让后退按钮执行其通常的操作即可。不要覆盖它,也不要开始新的活动。父 Activity 在堆栈中位于子 Activity 下方,因此它应该在子 Activity 完成时出现。

    【讨论】:

    • 我的答案保持不变。通常您不会覆盖 onBackPressed 而是允许后退按钮完成当前活动并将其从堆栈中删除。
    【解决方案4】:

    默认情况下,Android 会将 Activity 保留在堆栈中,因此当您从 Activity A 转到 Activity B 时,Activity A 会在您完成 Activity B 时返回 除非您执行其他一些操作,例如弄乱launchMode,从B返回完成A,等等。

    从您的代码中可以看出,您的问题应该通过在您的子活动中不覆盖 onBackPressed() 来解决。此外,您应该删除清单中子活动的 &lt;intent-filter&gt; 块。

    我建议阅读managing the activity lifecycletasks and back stack

    【讨论】:

    • 我在ClassAcivity 中有一个重写的 onbackpressed 方法。但是我尝试了你的解决方案,屏幕仍然在刷新
    【解决方案5】:

    首先,不需要重写 onBackPressed()。正如 Doug 提到的,父 Activity 位于堆栈中的子 Activity 下方,因此它会在子 Activity 完成后按时可见。

    有一个建议给你,因为 ActionBarActivity 已被弃用,所以最好在你的活动类中扩展 AppCompatActivity 类。

    我试图复制该问题但失败了。所以我创建了一个类。

    LandingPage.java

    public class LandingPage extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loading_page);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startActivity(new Intent(LandingPage.this, ClassActivity.class));
            }
        }, 1000);
    }
    
    }
    

    ClassActivity.java

    public class ClassActivity extends AppCompatActivity {
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.class_activity);
    
        //Do whatever you want to  do
    
    }
    public void editListener(View v)
    {
        Intent addNewClass = new Intent(ClassActivity.this,ClassActivityEdit.class);
        RelativeLayout buttonTableRow = (RelativeLayout) v.getParent();
        EditText getCourseID = (EditText) buttonTableRow.findViewById(R.id.courseNumberActivity);
        String courseIDString = getCourseID.getText().toString();
        addNewClass.putExtra("CourseIDString", courseIDString);
        startActivity(addNewClass);
    }
    }
    

    ChildActivityEdit.java

    public class ClassActivityEdit extends AppCompatActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.class_activity_edit);
        String course_no = getIntent().getStringExtra("CourseIDString");
        Toast.makeText(ClassActivityEdit.this,course_no,Toast.LENGTH_SHORT).show();
        //Do whatever you want to  do
    
    }
    }
    

    【讨论】:

      【解决方案6】:

      您的主要问题是您在子活动中覆盖了 onBackPressed。 我从您的代码中了解到的是- ClassActivity --> 父活动 ClassActivityEdit --> 子活动

      在清单中,android:noHistory="true" 是为子项指定的,即 ClassActivityEdit 活动。所以它不会存储在堆栈中。没有提到父母。

      在您的子活动的 onBackPressed 中,您将再次创建新的父活动,即使它已经存在于堆栈中。它就在您孩子的活动下方。

      即使您不覆盖 onBackPressed,父 Activity 仍会加载。在您的情况下,它正在创建许多父活动实例。

      还有一点,除非您希望您的 Activity 处理或响应特定操作,否则您无需在清单中为 Activity 添加 Intent 过滤器。根据文档,

      “意图过滤器指定活动、服务或广播接收器可以响应的意图类型。意图过滤器声明其父组件的功能——活动或服务可以做什么以及接收器可以做什么类型的广播句柄。它打开组件以接收广告类型的意图,同时过滤掉那些对组件没有意义的意图。

      【讨论】:

        【解决方案7】:

        您可以使用 Intent 轻松移回 Activity。但是您的背部活动刷新所有日期写入 onresum() 方法然后它会刷新数据

        【讨论】:

          【解决方案8】:

          在子活动中,我在 java 文件中有这段代码

          @Override
          public void onBackPressed()
            {
          
             Intent moveback =
                  new Intent(ClassActivityEdit.this, ClassActivity.class);
             startActivity(moveback);
             finish();
            }
          

          当您从父 Activity 启动子 Activity 时,您的父 Activity 移动到堆栈,并且子 Activity 显示在子 Activity 的 onBackPressed 事件中,您创建一个新的父 Activity instance 和在活动生命周期中首先调用 onCreate 事件,并在其中创建默认值的视图,因此当您单击子活动中的后退按钮而不创建父活动的新实例时,android 会显示具有先前 savedInstanceState 然后调用 onResume 事件。

          更多详情见Activity Life Cycle

          【讨论】:

            【解决方案9】:

            child activity 中的onBackPressed() 更改为此,或者您也可以从child activity 中删除onBackPressed()

            @Override
            public void onBackPressed(){
                super.onBackPressed();   // call super back pressed method  
            }
            

            当你从parent activity移动到child activity时,确保你没有finish()parent activity

            【讨论】:

              【解决方案10】:

              在启动 ClassActivity 意图时尝试使用FLAG_ACTIVITY_REORDER_TO_FRONT

              你说,

              在 ClassActivityEdit 活动中按下返回按钮时,Landing 活动再次闪烁,然后 ClassActivity 活动加载。

              您可能在 ClassActivity 的某个地方调用了 finish(),这将导致该活动从堆栈中删除。如果是这样,请将其删除。

              【讨论】:

                【解决方案11】:
                @Override
                public void onBackPressed(){
                  finish();
                  super.onBackPressed();
                }
                

                这将解决您的问题。 finish() 将销毁您的子活动,而 super.onBackPressed() 会将您重定向到父活动。

                【讨论】:

                  【解决方案12】:

                  你需要更换

                  startActivity(addNewClass);
                  

                  startActivityForResult(addNewClass,101);
                  

                  然后,您可以在 OnActivityResult 中刷新数据。

                  @Override
                  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                      if(requestCode==101){
                         if(resultCode==RESULT_CANCELED){
                             //refresh data accordingly
                         }else if(resultCode==RESULT_OK){
                             //refresh data accordingly
                         }
                      }
                  }
                  

                  【讨论】:

                  • 试过了,但你可以,但在调试时它会进入 onactivityresult 并返回到以前的活动
                  • 您可以在孩子的背部按下/销毁时闪现您的着陆活动,并且类活动仍然存在,为您提供所需的结果。抱歉,忘记提及这部分了。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-05-14
                  • 1970-01-01
                  相关资源
                  最近更新 更多