上一次聊了Activity的跳转和通信,虽然可以从一个Activity传数据给另一个被它所开启的Activity,
但是被开启的Activity如何将一些数据返回给前者呢?在实际运用中,常常需要打开一个Activity后,
让它计算处理一些数据后返回结果给前一个Activity,实现的过程主要靠的是三个方法:startActivityForResult、onActivityResul、setResult。
startActivityForResult(Intent intent, int requestCode),参数intent是开启参数Intent对象对应的Activity,其中 requestCode是用于区分不同Activity的。
setResult( int resultCode,Intent data);是被开启的Activity用Intent对象以键值对来返回数据给打开它的Activity,resultCode是告诉它要返回数据的Activity它自己的身份。
onActivityResult(int requestCode, int resultCode, Intent data)是当被打开的Activity被销毁之后,该方法会处理返回的数据。Intent对象携带返回的数据,另外两个参数int requestCode, int resultCode都可以用于区分返回数据的Activity的身份,只是一个是自己设定的编号,另一个是被打开的Activity设定的。
no代码say个JB。。
下面是一个非常简单的例子: MainActivity有两个按钮,一个点击跳转到ActivityA,一个跳转到ActivityB。按返回键时,ActivityA返回“open ActivityA”
,ActivityB返回“open ActivityB”,MainActivity将接受的字符串显示在TextView上。
MainActivity.Java:
public class MainActivity extends Activity { /** Called when the activity is first created. */ private Button A ; private Button B; private TextView tv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //根据控件的ID来取得代表控件的对象 A = (Button)findViewById(R.id.A); B = (Button)findViewById(R.id.B); tv = (TextView) findViewById(R.id.textView1); //将监听器的对象绑定到按钮对象上面 A.setOnClickListener(new CalculateListener()); B.setOnClickListener(new CalculateListener()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { String str = data.getStringExtra("who"); //判断requestCode,由自己的startActivityForResult确定 if(requestCode == 0) tv.setText(str); if(requestCode == 1) tv.setText(str); // 判断resultCode,由打开的Activity的setResult确定 // if(resultCode == 2) // // tv.setText(str); // if(resultCode == 3) // // tv.setText(str); } class CalculateListener implements OnClickListener{ @Override public void onClick(View v) { Intent intent = new Intent(); switch(v.getId()){ //跳转到ActivityA case R.id.A: intent.setClass(MainActivity.this, ActivityA.class); MainActivity.this.startActivityForResult(intent, 0); break; //跳转到ActivitB case R.id.B: intent.setClass(MainActivity.this, ActivityB.class); MainActivity.this.startActivityForResult(intent, 1); break; default: break; } } } }ActivityA:
public class ActivityA extends Activity{ private TextView resultView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.a); Intent data = new Intent(); data.putExtra("who", "open ActivityA"); //将数据返回,并确定resultCode以向MainAcitivity表明身份 setResult(2, data); } }ActivityB:
public class ActivityB extends Activity{ private TextView resultView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.b); Intent data = new Intent(); data.putExtra("who", "open ActivityB"); ////将数据返回,并确定resultCode以向MainAcitivity表明身份 setResult(3, data); } }
MainActivity:
点击按钮“打开ActivityA”:
点击返回键,激动人心的时刻到了!
已经得到返回的数据啦!!
再点击“打开ActivityB”:
后退键:
ActivityB也成功返回了数据!
把注释的这段话
// 判断resultCode,由打开的Activity的setResult确定 // if(resultCode == 2) // // tv.setText(str); // if(resultCode == 3) // // tv.setText(str);
//判断requestCode,由自己的startActivityForResult确定 if(requestCode == 0) tv.setText(str); if(requestCode == 1) tv.setText(str);
最后说下Activity的启动模式。在android系统中,每个应用都会有一个任务栈的东西管理Activity,每当创建新的Activity实例,就被将该实例压入任务栈中,显示在屏幕的是当前的Activity。当Activity被销毁,就把栈顶Activity弹出栈。Activity的启动模式就和任务栈息息相关。一般有四种启动模式:
1.Standard: 默认的标准模式,调用startActivity就会创建新的Activity的实例,每次添加到任务栈顶。适用于大部分情况。(当栈顶有多个相同的Activit实例的时候会出现按后退键后当前Activity仍然停留在同一个Activtiy的情况)
2. singleTop: 如果开启的Activity在栈顶(非栈顶还是会创建),则调用startActivity就不会创建新的Activity的实例,不调用onCreate方法而是调用onNewIntent(避免栈顶的Activity被重复创建,避免按后退后仍然在同一个Activity的情况)。
应用场景:浏览器书签。
3.singleTask:保证任务栈中只有一个该Activity的实例,若该Activity的实例已经存在于任务栈了,则再次开启会服用之前的实例,并且将在任务栈中于其之上的Activity全部清空!
应用场景:浏览器Activity。一般用于消耗内存大的Activity实例以节约内存。
4.singleInstance:单一实例,手机操作系统只有一个实例(不同应用打开也是共享同一个实例)拥有单独、独立的任务栈(即专门开一个任务栈给它用),任务栈只有一个实例。(类似java的单例模式)
应用场景:手机来电界面。