launchMode带来的onActivityResult失效问题

来源:互联网 发布:电影 《人工智能》 编辑:程序博客网 时间:2024/06/03 22:15

  项目开发中遇到一个问题,由ActivityA跳转到ActivityB时,如果ActivityB设置了launchMode,并且B界面finish时需要返回给ActivityA一些数据,这时候ActivityA对于ActivityB的onActivityResult()方法可能会出现一些问题。下面写一个简单的小demo来验证一下。
  A中有一个按钮进行界面跳转到B,

button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent=new Intent(A.this,B.class);                startActivityForResult(intent,REQUST_CODE);            }        });

  B中按钮finish,返回A界面。

finish.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent();                intent.putExtra("test", "data from B");                setResult(RESULT_OK,intent);                finish();            }        });

  最后在A中进行处理,

 @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (resultCode==RESULT_OK){            String result=data.getStringExtra("test");            Toast.makeText(getApplicationContext(),"RESULT_OK  "+result,Toast.LENGTH_SHORT).show();        }        if (resultCode==RESULT_CANCELED){            Toast.makeText(getApplicationContext(),"RESULT_CANCELED",Toast.LENGTH_SHORT).show();        }    }

  关于launchMode就不详细讲解了,这里简单说一下。
standard:默认的启动模式,每次启动都会在当前栈中重新生成一个新的 Activity实例。
singleTop:启动时先去检查栈顶是不是当前Activity实例,是的则直接使用,不 是的就重新创建。
singleTask:保证当前栈中只有自己的一个实例,通常的做法是,如果在栈中发现了自己的Activity实例,就将这个实例之上的其他Activity实例统统赶走,使自己成为栈顶。
singleInstance:这个模式最霸道,会重新建一个栈,把自己的Activity实例放进去,并且不会再放入其他Activity实例。

  先测试一下standard模式,清单文件ActivityB中加入android:launchMode="standard",断点调试。点击A中按钮,跳转到B,点击B中按钮,进入断点,如下图所示,这是A成功收到B返回过来的数据,standard模式启动Activity对onActivityResult没有影响。standard模式

  接下来以同样的方式测试singleTop模式,测试结果与standard模式一样,这里不再赘述。
  接着将B的启动模式改为singleTask继续断点测试,这次结果就比较出人意料,与之前有很大区别。当我点击A中跳转按钮时,就直接进入了onActivityResult中的断点,注意这里进入断点的时间,并不是点击B中finish按钮后才进入断点。这里我就产生了一个疑惑,当我点击按钮去进行跳转按钮之后,是不是压根就没有进入B界面。为了验证一下这个问题,我在B界面的onCreate()方法上也打上断点,来看一下代码的执行顺序。这次,当我点击A中按钮后。首先执行的依然是A中的onActivityResult方法,那么此时的resultCode是多少呢?请注意看下图,

singleTask模式
  可以看到此时的resultCode是一个值为0的常量,RESULT_CANCELED,所以这样是完全没有办法接收数据的,也就是在调用startActivityForResult()之后就直接调用了onActivityResult(),并给出了一个值为0的结果码。至于具体原因,暂时还没有想到比较合理的解释,哪位大牛知道原因的和小弟说道说道。
  最后来测试一下singleInstance模式,发现和singleTask模式一样。
  所以,如果当你要跳转的Activity的启动模式为singleTask或者singleInstance时,会导致跳转前Activity无法收到跳转后Activity返回的数据,在这里要注意一下。

0 0