Android back键ANR,与onPause,onDestory “延迟执行”的问题研究

我前面有篇文章提到 这个问题的现象记录http://blog.csdn.net/luohaowang320/article/details/18088425

1.首先,分析activity back键,响应出现 ANR的问题。

这个问题是由于在manifest的activity中 使用 Theme.NoDisplay,不显示该Activity 导致的。

android:theme="@android:style/Theme.NoDisplay"

测试代码很简单,将一个application的Activity添加上面属性,桌面运行,看不到任何界面,og的日志可以,看到该onResume已执行,你可以照常进行其他的交互,滑动分页、打开其他的应用,但是不能碰“BACK”键,否则就会出现“ANR”。深层次的原因,暂时还不清楚,有大侠知道,欢迎回复解答下。

2.解决“ANR"bug : 在改Activity的 onCreate中添加

moveTaskToBack(true);

这样,就可以正常响应back键了,但是,会导致另外的问题:onPause onDestroy 延迟执行。

当然,这个moveTaskToBack最好是写在onResume中,不然,再次显示该Activity的时候,还是会出现 ANR的问题。

3.onPause onDestroy 延迟执行分析验证。

情况一:

app A代码清单如下:


public class AMainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Log.i(getClass().getSimpleName(), "onCreate--taskId=" + getTaskId());

		findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Log.i(getClass().getSimpleName(), "onClick");
				ComponentName componentName = 
						new ComponentName("com.example.testlanchmode2", "com.example.testlanchmode2.BMainActivity");
				//启动 app2 的BActivity
				startActivity(new Intent().setComponent(componentName));
			}
		});
	}

manifest 配置:singleInstance

        <activity
            android:name="com.example.testlunchmode.AMainActivity"
            android:launchMode="singleInstance"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

app B 代码清单:

public class BMainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Log.i(getClass().getSimpleName(), "onCreate--taskId=" + getTaskId());
		// initClick();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		Log.i(getClass().getSimpleName(), "onResume--taskId=" + getTaskId());
		// 移至后台
		moveTaskToBack(true);
		super.onResume();
	}

manifest:

Theme.NoDisplay,singleInstance

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
       android:theme="@android:style/Theme.NoDisplay"
        >
        <activity
            android:name="com.example.testlanchmode2.BMainActivity"
            android:launchMode="singleInstance"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

运行的log:

01-23 15:46:02.908: I/AMainActivity(2704): onCreate--taskId=3
01-23 15:46:02.908: I/AMainActivity(2704): onStart--taskId=3  
01-23 15:46:02.908: I/AMainActivity(2704): onResume--taskId=3

01-23 15:46:06.718: I/(2704): onClick
----启动BActivity---

01-23 15:46:06.718: I/ActivityManager(1075): START {cmp=com.example.testlanchmode2/.BMainActivity u=0} from pid 2704

01-23 15:46:06.878: I/AMainActivity(2704): onPause--taskId=3

01-23 15:46:06.908: I/ActivityManager(1075): Start proc com.example.testlanchmode2 for activity com.example.testlanchmode2/.BMainActivity: pid=2746 uid=10046 gids={1028}
01-23 15:46:07.048: I/BMainActivity(2746): onCreate--taskId=4
01-23 15:46:07.048: I/BMainActivity(2746): onStart--taskId=4
01-23 15:46:07.048: I/BMainActivity(2746): onResume--taskId=4
01-23 15:46:07.048: I/ActivityManager(1075): moveTaskToBack: 4
01-23 15:46:07.058: I/BMainActivity(2746): onPause--taskId=4
01-23 15:46:07.068: I/AMainActivity(2704): onResume--taskId=3
01-23 15:46:07.088: I/BMainActivity(2746): onStop--taskId=4
----按Back键---
01-23 15:46:12.108: I/AMainActivity(2704): onBackPressed--taskId=3  
01-23 15:46:12.108: I/AMainActivity(2704): finish--taskId=3
01-23 15:46:12.278: I/AMainActivity(2704): finish--taskId=3
01-23 15:46:12.278: I/AMainActivity(2704): onPause--taskId=3

----再次启动AActivity
01-23 15:46:21.458: I/ActivityManager(1075): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.testlunchmode/.AMainActivity u=0} from pid 1294
01-23 15:46:21.628: D/---->>>>(1294): NAME is com.example.testlunchmode.AMainActivity

01-23 15:46:21.678: I/AMainActivity(2704): onCreate--taskId=5
01-23 15:46:21.688: I/AMainActivity(2704): onStart--taskId=5  
01-23 15:46:21.688: I/AMainActivity(2704): onResume--taskId=5
01-23 15:46:21.808: I/ActivityManager(1075): Displayed com.example.testlunchmode/.AMainActivity: +175ms (total +14s925ms)
01-23 15:46:22.108: I/AMainActivity(2704): onStop--taskId=3  
01-23 15:46:22.108: I/AMainActivity(2704): onDestroy--taskId=3  
----问题出现了,前一个task中的AActivity 到现在才销毁?我的AActivity不也是 singleInstance的么,为何此时还创建了第二个task?尽管前面的task已经挂掉。

----正常back---
01-23 15:46:47.458: I/AMainActivity(2704): onBackPressed--taskId=5  
01-23 15:46:47.458: I/AMainActivity(2704): finish--taskId=5
01-23 15:46:47.638: I/AMainActivity(2704): onPause--taskId=5
01-23 15:46:48.278: I/AMainActivity(2704): onStop--taskId=5  
01-23 15:46:48.278: I/AMainActivity(2704): onDestroy--taskId=5  

----再次启动A---
01-23 15:46:55.098: I/ActivityManager(1075): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.testlunchmode/.AMainActivity u=0} from pid 1294
01-23 15:46:55.338: I/AMainActivity(2704): onCreate--taskId=6
01-23 15:46:55.338: I/AMainActivity(2704): onStart--taskId=6  
01-23 15:46:55.338: I/AMainActivity(2704): onResume--taskId=6
----启动B---
01-23 15:46:56.978: I/(2704): onClick
01-23 15:46:56.978: I/ActivityManager(1075): START {cmp=com.example.testlanchmode2/.BMainActivity u=0} from pid 2704
01-23 15:46:57.148: I/AMainActivity(2704): onPause--taskId=6
01-23 15:46:57.158: I/BMainActivity(2746): onStart--taskId=4
01-23 15:46:57.158: I/BMainActivity(2746): onResume--taskId=4
01-23 15:46:57.158: I/ActivityManager(1075): moveTaskToBack: 4
01-23 15:46:57.168: I/BMainActivity(2746): onPause--taskId=4
01-23 15:46:57.188: I/BMainActivity(2746): onStop--taskId=4
01-23 15:46:57.198: I/AMainActivity(2704): onResume--taskId=6
----A back---
01-23 15:47:02.128: I/AMainActivity(2704): onBackPressed--taskId=6  
01-23 15:47:02.128: I/AMainActivity(2704): finish--taskId=6
01-23 15:47:02.308: I/AMainActivity(2704): onPause--taskId=6

---启动A----
01-23 15:47:21.728: I/ActivityManager(1075): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.testlunchmode/.AMainActivity u=0} from pid 1294
01-23 15:47:21.938: I/AMainActivity(2704): onCreate--taskId=7
01-23 15:47:21.938: I/AMainActivity(2704): onStart--taskId=7  
01-23 15:47:21.938: I/AMainActivity(2704): onResume--taskId=7
01-23 15:47:22.358: I/AMainActivity(2704): onStop--taskId=6  
01-23 15:47:22.368: I/AMainActivity(2704): onDestroy--taskId=6  

运行后的效果就是那样,A 启动B,然后back,A的onStop,onDestroy 就会“延时”。

情况二:

B activity manifest 去掉 singleInstance 设置

效果与情况一一样,貌似是 moveTaskToBack的影响。

情况三:

A activity manifest 去掉 singleInstance 设置,B activity manifest 保留singleInstance 

效果与情况一,还是一样。

情况四:单独去掉B activity的 Theme.NoDisplay,还是一样

情况五:单独去掉B activity的 Theme.NoDisplay,然后 按键去触发moveTaskToBack 。流程就是正常的。why?

你可能感兴趣的:(Android back键ANR,与onPause,onDestory “延迟执行”的问题研究)