Android onActivityResult记录

2017-04-15  本文已影响1773人  谢不再

面试时被问到一个问题:Activity A通过startActivityForResult()启动Activity B,在B没有被finish()之前,A的onActivityResult()就返回了失败的结果。为什么会出现这种情况?

两个相关的方法

  • startActivityForResult()

一般我们是这样使用,在MainActivity.java中

public static final int  REQUEST_CODE=1001;
                         ...
public void click(View view){
       Intent intent=new Intent(MainActivity.this,NewActivity.class);
       intent.putExtra("msgA","我是蛮大人");
       startActivityForResult(intent,REQUEST_CODE);
}

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i(TAG, "MainActivity onActivityResult");
        if (requestCode==REQUEST_CODE&&resultCode==RESULT_OK){
            String msg=data.getStringExtra("msgB");
            Log.i(TAG, "onActivityResult: msgB="+msg);
        }
    }

在NewActivity.java中

public void click(View view){
        Intent data=new Intent();
        data.putExtra("msgB","哇咔咔");
        setResult(RESULT_OK,data);
        finish();
    }

我们看下Activity.java

/**
 *  @param requestCode If >= 0, this code will be returned in
     *                    onActivityResult() when the activity exits.
**/
public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

方法注释提到中参数requestCode需要大于或等0,这里会出现第一个问题:onActivityResult()方法不会被调用?
答:参照 使用正确的RequestCoderequestCode使用-1或者[0,65536)中的某一个int值时不会报错,但是使用-1时,onActivityResult()不会被调用。
继续看 Activity.java API

 /**1、For example, if the activity you are launching uses the singleTask launch mode,
 *  it will not run in your task and thus you will immediately receive a cancel result.
 *  2、As a special case, if you call startActivityForResult() with a requestCode>= 0 
 *  during the initial onCreate(Bundle savedInstanceState)/onResume() of your activity, 
 *  then your window will not be displayed until a result is returned back from the started activity.
**/
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
                             ...
}

对于注释中提到的第一点,如果将要启动的Activity启动模式是singleTask,会立即回调onActivityResult()。
测试1,在AndroidManifest.xml配置

<activity android:name=".NewActivity"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

结果如下:

                                                  //进入MainActivity
04-15 00:06:34.777 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onCreate
04-15 00:06:34.777 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStart
04-15 00:06:34.777 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onResume
                                                  //点击button进入NewActivity
04-15 00:06:59.867 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onPause
04-15 00:06:59.927 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onCreate: msgA=我是蛮大人
04-15 00:06:59.927 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onStart
04-15 00:06:59.927 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onResume
04-15 00:07:00.427 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStop
                                                   //点击button关闭NewActivity
04-15 00:19:28.320 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onPause
04-15 00:19:28.330 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onActivityResult
04-15 00:19:28.330 29915-29915/com.example.testing.activityresulttest I/Activity_Test: onActivityResult: msgB=哇咔咔
04-15 00:19:28.330 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onRestart
04-15 00:19:28.330 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStart
04-15 00:19:28.330 29915-29915/com.example.testing.activityresulttest I/Activity_Test: MainActivity onResume
04-15 00:19:28.660 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onStop
04-15 00:19:28.660 29915-29915/com.example.testing.activityresulttest I/Activity_Test: NewActivity onDestroy

可以看到,并不会立即回调onActivityResult()。
测试2,在代码中配置

//AndroidManifest.xml
<activity android:name=".NewActivity"/>
        <!--<activity android:name=".NewActivity"-->
            <!--android:launchMode="singleTask">-->
            <!--<intent-filter>-->
                <!--<action android:name="android.intent.action.VIEW"/>-->
                <!--<category android:name="android.intent.category.DEFAULT"/>-->
            <!--</intent-filter>-->
        <!--</activity>-->
            ---------------------------------------------------
//MainActivity.java
public void click(View view) {
        Intent intent=new Intent(MainActivity.this, NewActivity.class);
        //add for test
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("msgA","我是蛮大人");
        startActivityForResult(intent, REQUEST_CODE);
    }

结果如下:

                                                           //进入MainActivity
04-15 00:29:36.480 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onCreate
04-15 00:29:36.480 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStart
04-15 00:29:36.480 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onResume
                                                           //点击button进入NewActivity
04-15 00:29:51.390 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onPause
04-15 00:29:51.390 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onActivityResult
04-15 00:29:51.390 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onResume
04-15 00:29:51.400 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onPause
04-15 00:29:51.440 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onCreate: msgA=我是蛮大人
04-15 00:29:51.450 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onStart
04-15 00:29:51.450 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onResume
04-15 00:29:51.970 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStop
                                                             //点击button关闭NewActivity
04-15 00:30:23.690 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onPause
04-15 00:30:23.700 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onRestart
04-15 00:30:23.700 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onStart
04-15 00:30:23.700 26905-26905/com.example.testing.activityresulttest I/Activity_Test: MainActivity onResume
04-15 00:30:24.070 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onStop
04-15 00:30:24.070 26905-26905/com.example.testing.activityresulttest I/Activity_Test: NewActivity onDestroy

可以看到,onActivityResult()在NewActivity创建之前被调用了,而且有意思的是生命周期onPause()>onActivityResult()>onResume()>onPause(),这个待分析,高手可以指点下。
这里可以引出第二个问题:也就是文章开头提到的面试题,onActivityResult()在被启动Activity退出前就被调用了。
答:这个可能跟将要启动的Activity的启动模式有关系。
另有时候,可能会需要知道第三个问题,onActivityResult()是在什么时候被调用的,而setResult()应该在什么时候调用?
答:很明显,onActivityResult()正常情况下在onRestart()之前被调用;而通常情况下,我们通过startActivityForResult()启动一个activity后,会进行一些处理得到我们要返回的数据时调用,并且随之我们调用finish()退出Activity返回启动它的Activity。
未完待续。。。

上一篇下一篇

猜你喜欢

热点阅读