您的位置:首页 > 移动开发 > Android开发

Android Activity学习之 startActivityForResult() & 主界面连接多个子功能模块

2014-06-25 13:16 357 查看



一、startActivityForResult()的用法


在一个主界面(主Activity)上能连接往许多不同子功能模块(子Activity上去),当子模块的事情做完之后就回到主界面,或许还同时返回一些子模块完成的数据交给主Activity处理。


目的: A.java 是主界面,B.java 是子功能模块,要从A启动B,B干完活之后把结果汇报给A

先看 A.java 的相关代码
<span style="font-weight: normal;">//-- A.java --//
//要做两件事情,第一是用 startActivityForResult() 启动B,其次是回收B的结果
//启动B
Intent bintent = new Intent(A.this, B.class);
//设置 bintent的Bundle的一个值
String bsay = "Hello, this is B speaking";
bintent.putExtra("listenB", bsay)
startActivityForResult(bintent,0); // 参数(Intent intent, Int requestCode)的requestCode 对应下面回收Bundle时识别用的
//重写onActivityResult()来处理返回的数据,建议先看B.java 的代码再回来看这里比较好理解
//这理有三个参数 requestCode, resultCode, data
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) { //resultCode为回传的标记,我在B中回传的是RESULT_OK
case RESULT_OK:
Bundle b=data.getExtras();  //data为B中回传的Intent
String str=b.getString("ListenB");//str即为回传的值"Hello, this is B speaking"
/* 得到B回传的数据后做什么... 略 */</span>
<span style="font-weight: normal;">break;
default:</span>
<span style="font-weight: normal;">break;
}
}</span>
<span style="font-weight: normal;">//-- B.java --//
// 用 setResut() 准备好要回传的数据后,只要使用finish()的方法就能把打包好的数据发给A且运行onActivityResult()部分的代码
Intent aintent = new Intent(B.this, A.class);
/* 将数据打包到aintent Bundle 的过程略 */
setResut(RESULT_OK,aintent); //这理有2个参数(int resultCode, Intent intent)
... ...
finish();</span>


startActivityForResult(Intent intent, Int requestCode)

intent 传给B的,requestCode用于在onActivityResult()区别哪个子模块回传的数据,可随便取只要requestCode >=0。

setResut(int resultCode, Intent intent)

这里B子模块有几种不同的返回结果,用 resultCode参数予以区分,其值在非特殊情况下使用 RESULT_OK
,sdk有说明;

intent 传回给A的onActivityResult()。

onActivityResult(int requestCode, int resultCode, Intent intent)

三个参数与上面相对应,如果不对requestCode和resultCode 加以区分,若有activity setResult到了A,onActivityResult()会无差别处理。


以上转载:http://www.cnblogs.com/mubai/archive/2011/09/21/2183816.html


二、startActivityForResult和setResult详解

与startActivity的不同之处在于
1、startActivity( ) 

仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startActivity( )。

2、startActivityForResult( ) 

可以一次性完成这项任务,当程序执行到这段代码的时候,假若从T1Activity跳转到下一个Text2Activity,而当这个Text2Activity调用了finish()方法以后,程序会自动跳转回T1Activity,并调用前一个T1Activity中的onActivityResult( )方法。

相关函数:
startActivityForResult(Intent intent, Int requestCode)

setResut(int resultCode, Intent intent)

onActivityResult(int requestCode, int resultCode, Intent intent)

简单例子介绍:

1.跳转的时候不是采用startActivity(intent) 这个方法,而是startActivityForResult(intent, 0)

Intent intent=new Intent();
intent.setClass(A.this, B.class);
Bundle bundle=new Bundle();
String str1="aaaaaa";
bundle.putString("str1", str1);
intent.putExtras(bundle);
startActivityForResult(intent, 0);//这里采用startActivityForResult来做跳转,此处的0为一个依据,可以写其他的值,但一定要>=0
2.重写onActivityResult方法,用来接收B回传的数据。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) { //resultCode为回传的标记,我在B中回传的是RESULT_OK
case RESULT_OK:
Bundle b=data.getExtras(); //data为B中回传的Intent
String str=b.getString("str1");//str即为回传的值
break;
default:
break;
}
}


3.在B中回传数据时采用setResult方法,并且之后要调用finish方法。

setResult(RESULT_OK, intent); //intent为A传来的带有Bundle的intent,当然也可以自己定义新的Bundle
finish();//此处一定要调用finish()方法


Android activity的setResult()在什么时候调用(重点也是难点)

如果在startActivityForResult起来的Activity里面设置setResult,结果并不会马上返回给parent的Activity,只有当前Activity被finish,结果才会被发送给parent的onActivityResult去处理!

如果一个activity要返回数据到启动它的那个activity,可以调用setResult()方法。那什么时候去调用setResult()方法返回数据呢?

看一下源码就明白了:
<pre name="code" class="java">public final void setResult(int resultCode, Intent data) {
synchronized (this) {
mResultCode = resultCode;
mResultData = data;
}
}

public void finish() {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (Config.LOGV) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}



这段代码可以看出activity返回result是在被finish的时候,也就是说调用setResult()方法必须在finish()之前。那么如果在如下方法中调用setResult()也有可能不会返回成功: onPause(), onStop(), onDestroy(),因为这些方法调用不一定是在finish之前的,当然在onCreate()就调用setResult肯定是在finish之前的

按BACK键从一个Activity退出来的,一按BACK,android就会自动调用Activity的finish()方法,然后设置resultCode为RESULT_CANCELED,也就不会返回任何数据了 .解决方法就是在Activity里面捕获按BACK的事件,捕获到之后先setResult,然后自己来调用finish,就搞定了……把BACK事件直接自己给吞了

@Override
public void onBackPressed() {
Log.i(TAG, "onBackPressed");
setResult(Const.LIVE_OK);
super.onBackPressed();
}


当然还可以在onCreate()就调用setResult,不过我觉得这种方法没有重写onBackPressed()方法好.

以上转载:http://www.cnblogs.com/lijunamneg/archive/2013/02/05/2892616.html


三、onActivityResult传值的使用

多个activity之间的传值 其实就是onActivityResult,但还有一个action的问题,就是在主xml中添加自己的action以便于识别,最后子activity调用finansh()。

public class Wizard extends Activity {

private TextView step1result, step2result, step3result;

public static final String INTENT_STEP1 = "com.novoda.STEP1";
public static final String INTENT_STEP2 = "com.novoda.STEP2";
public static final String INTENT_STEP3 = "com.novoda.STEP3";

private static final int STEP1 = 1;
private static final int STEP2 = 2;
private static final int STEP3 = 3;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wizard);

this.step1result = (TextView)findViewById(R.id.step1result);
this.step2result = (TextView)findViewById(R.id.step2result);
this.step3result = (TextView)findViewById(R.id.step3result);

startActivityForResult(new Intent(Wizard.INTENT_STEP1), STEP1);
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case STEP1:
this.step1result.setText(data.getStringExtra("STEP1RESULT"));
startActivityForResult(new Intent(Wizard.INTENT_STEP2), STEP2);
break;
case STEP2:
this.step2result.setText(data.getStringExtra("STEP2RESULT"));
startActivityForResult(new Intent(Wizard.INTENT_STEP3), STEP3);
break;
case STEP3:
this.step3result.setText(data.getStringExtra("STEP3RESULT"));
break;
}
}
}

public class Step1 extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.step1);

Button nextStep = (Button)findViewById(R.id.goto2);
nextStep.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent it = new Intent();
it.putExtra("STEP1RESULT", ((EditText)findViewById(R.id.step1value)).getText()
.toString());
setResult(Activity.RESULT_OK, it);
finish();
}
});
}
}


后面的step2 step3都是一样的了

然后还有主xml
<pre name="code" class="java"><application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Wizard" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name=".Step1" android:label="Step1">
<intent-filter>
<action android:name="com.novoda.STEP1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity android:name=".Step2" android:label="Step2">
<intent-filter>
<action android:name="com.novoda.STEP2" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity android:name=".Step3" android:label="Step3">
<intent-filter>
<action android:name="com.novoda.STEP3" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>



以上转载:http://wang-peng1.iteye.com/blog/632833
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: