【问题标题】:How to trigger onPause programmatically in android activity如何在android活动中以编程方式触发onPause
【发布时间】:2013-07-10 20:05:55
【问题描述】:

我正在尝试研究如何模拟暂停活动以调试我的应用程序。我希望调用 onPause 但不调用 onStop。我只是想尝试一个暂停恢复周期,并正在寻找一些我可以调用的代码(例如在按下按钮后)来触发它。

有什么想法吗?

我看到有人建议在其他线程中按下主页按钮,但是当我这样做时会停止应用程序并调用 onStop 和 onPause,所以这并不是我想要的。

【问题讨论】:

标签: android activity-lifecycle


【解决方案1】:

取自link:最简单的方法是在您的活动之上添加一个半透明活动。我自己做了测试,onStop 确实没有被调用:

透明活动:

public class TransparentActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        setContentView(R.layout.transparent_layout);
    }
}

transparent_layout 可以使用任何简单的布局,但棘手的部分是在 Manifest 中:

<activity
            android:name=".TransparentActivity"
            android:theme="@style/Theme.Transparent" >
        </activity>

styles.xml 中的位置:

<style name="Theme.Transparent" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>

然后在启动活动中:

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btnNext).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, TransparentActivity.class));
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("TSTAct", "#onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("TSTAct", "#onStop");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("TSTAct", "#onResume");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("TSTAct", "#onStart");
    }
}

打开 TransparentActivity 时,我只能在 Logcat 中看到:

07-10 23:35:28.323: D/TSTAct(27180): #onPause

没有onStop 电话。

【讨论】:

  • 谢谢,我会试一试 - 我尝试了类似的方法,在我的屏幕上显示了一个对话框,但失败了,但我没有为此创建单独的活动
  • 古纳尔先生总结了。但我只想说,并非所有半透明活动都会调用 onPause。例如,Dialog,因为对话框使用当前活动的上下文。我希望我澄清一下。
  • 好的,试过了,这对我有用,所以谢谢。我宁愿希望有一种方法可以在一行左右的时间内完成,而无需制作 gui 元素和活动。所以我也可以看看我今天发现的这个 Instrumentation 类(我是 Android 新手),然后看看如何从那里开始。
  • 你问如何模拟这个以调试应用程序......你没有提到任何 TDD。但是如果你走那条路,你会发现确实这样更容易。您只需花费一些时间来适应 TDD。
  • 是的,我希望我可以在没有 TDD 的情况下用一两行来完成(这完全是另一回事)。至少您的透明片段建议在不在测试环境中时确实可以满足我的需要,并且我找不到更好的方法
【解决方案2】:

简单的方法,从 Mainactivity 我将使用 Intent 调用另一个活动。在清单中,我将定义为

    <activity android:name=".AnotherActivity"
              android:theme="@style/Theme.AppCompat.Dialog" >
    </activity>

意味着我将添加样式为“Theme.AppCompat.Dialog”的另一个活动意味着这将看起来像对话框。

如果您使用 Intent 从 Main Activity 调用它,那么“AnotherActivity”将显示为 Dialog ,它将进入 Main Activity 之上,此时主 Activity 将处于 onPause 状态(它不会调用 MainActivity 的 onStop 状态)

【讨论】:

    【解决方案3】:

    1) 定义一个方法。

    public static Instrumentation callLifeCycleMethod()
    {
       return new Instrumentation();
    }
    

    2) 调用方法。

    callLifeCycleMethod().callActivityOnDestroy(MainActivity.this);
    

    callLifeCycleMethod().callActivityOnPause(MainActivity.this);
    

    【讨论】:

      【解决方案4】:

      调试 onPause 和 onResume 发生的情况的另一种方法是使用 Android 测试框架。在活动测试中,您可以获得一个 Instrumentation 对象,然后触发暂停和恢复:

      import android.app.Instrumentation;
      import android.test.ActivityInstrumentationTestCase2;
      
      public class LaunchActivityTest extends ActivityInstrumentationTestCase2<LaunchActivity> {
      
          private LaunchActivity launchActivity;
      
          public LaunchActivityTest() {
              super(LaunchActivity.class);
              // TODO Auto-generated constructor stub
          }
      
          @Override
          protected void setUp() throws Exception {
      
              super.setUp();
              launchActivity = getActivity();
          }
      
          @Override
          protected void tearDown() throws Exception {
      
              super.tearDown();
          }
      
          public void testPause() {
      
              Instrumentation ins = getInstrumentation();
              ins.callActivityOnPause(launchActivity);
              assertEquals(true, true);
              ins.callActivityOnResume(launchActivity);
          }
      
      }
      

      请注意,我在这里只使用了一个虚拟断言。顺便说一句,我还不确定如何断言这些方法是在 Java 中调用的

      【讨论】:

        【解决方案5】:

        另一种选择可能是使用反射在 Activity 中调用私有方法 performPause。 这样的事情原则上应该有效:

        Method method = myactivity.getClass().getSuperclass().getDeclaredMethod("performPause");
        method.setAccessible(true);
        method.invoke(myactivity);
        

        注意我还没有测试它

        【讨论】:

          猜你喜欢
          • 2017-03-27
          • 2014-07-17
          • 2015-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-16
          • 2017-07-15
          相关资源
          最近更新 更多