美文网首页
Android onActivityResult记录

Android onActivityResult记录

作者: 谢不再 | 来源:发表于2017-04-15 01:12 被阅读1773次

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

    两个相关的方法

    • startActivityForResult()
    • onActivityResult()

    一般我们是这样使用,在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。
    未完待续。。。

    相关文章

      网友评论

          本文标题:Android onActivityResult记录

          本文链接:https://www.haomeiwen.com/subject/rdsgattx.html