细说onActivity、onNewIntent(intent)

使用startActivityForResult一定要注意Activity的启动模式。如果不注意执行startActivityForResult,没等到被调用的 Activity 返回,onActivityResult() 就被执行了。将lanchMode设置为标准模式就好了。

看api的注释: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.

 三个Activity连传intent案例

分享一个我在实际开发中遇到的例子。

问题描述如下:

要求最一个商家注册功能的实现,里面有个服务选项,这个服务选项是有两级分类组成,没个用户只能选择一级分类的下面的二级分类,不可以跨组选分类。选择后肯定要将数据显示到注册页面上。

我的实现方法是这样的:设注册页面的Activity为A,一级分类的Activity为B,二级分类的Activity为C。

主要看A中Intent启动的是B,如何收到C的数据的!其他数据可以忽略,可以根据项目中的需要,传递。

A:

public class A_Activity extends Activity {
 private TextView mTv_a;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.a_activity);
  mTv_a = (TextView) findViewById(R.id.tv_a);
  mTv_a.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    Intent intent = new Intent(A_Activity.this, B_Activity.class); // 指定启动B
    intent.putExtra("DATA1", "从A中传入的数据");
    startActivityForResult(intent, 1);
   }
  });
 }
 @Override
 protected void onActivityResult(int requestCode, int resultCode,
   Intent intent) {
  // TODO Auto-generated method stub
  if(requestCode == 1 && resultCode == 1){
   Log.d("TAG",intent.getStringExtra("DATA3"));
  }
  
  super.onActivityResult(requestCode, resultCode, intent);
 }
}

B:

public class B_Activity extends Activity {
 private TextView mTv_b;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.b_activity);
  
  mTv_b = (TextView) findViewById(R.id.tv_b);
  mTv_b.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    Intent intent = new Intent(B_Activity.this,
      C_Activity.class);
    intent.putExtra("DATA2", "从B中传入的数据");
    startActivityForResult(intent, 2);
   }
  });
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
  // TODO Auto-generated method stub
  if(requestCode == 2 && resultCode == 2){
   B_Activity.this.setResult(1, intent);
   B_Activity.this.finish();
  }
  super.onActivityResult(requestCode, resultCode, intent);
 }
}

C:

public class C_Activity extends Activity {
 private TextView mTv_c;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.c_activity);
  mTv_c = (TextView) findViewById(R.id.tv_c);
  mTv_c.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    Intent intent = getIntent();
    intent.putExtra("DATA3", "从C中传入的数据");
    C_Activity.this.setResult(2, intent);
    C_Activity.this.finish();
   }
  });
 }
}

在B中 B_Activity.this.setResult(1, intent);
   B_Activity.this.finish();
是关键。Android中肯定有相关方法处理这样的功能,我这种方法可能算是麻烦的了,大家如果有其他方法,欢迎留言,提出。

第二种方法是通过onNewIntent实现,这个就更加简单了。

 

 

onNewIntent:

当从栈中启动一个已经存在的Activity时,系统不会再执行onCreate方法,而是执行onNewIntent方法

(1)Activity第一启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent().

(2) 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume().

(3)如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。

所以如果使用onNewIntent,执行返回的操作,1、要将此Activity的lanchMode设置为singleTask。2、另外一个Activity要通过intent请求此Activity。也可以通过Intent.FLAG_ACTIVITY_SINGLE_TOP标志启动Activity,效果跟android:launchmode="singleTask"一样。 

另外,不要忘记,系统可能会随时杀掉后台运行的Activity,如果这一切发生,那么系统就会调用onCreate方法,而不调用onNewIntent方法,一个好的解决方法就是在onCreate和onNewIntent方法中调用同一个处理数据的方法。

 

如何区别从Activity B跳转到onNewIntent操作的Activity A呢?

是在Activity B中的intent中设置标志值,然后通过if判断:

if (intent.getBooleanExtra("LOGIN", false)) {}

你可能感兴趣的:(数据,intent,三个Activit,、onNewIntent)