Activity之onActivityResult与setResult

xiaoxiao2021-02-28  87

在Android app开发当中,我们经常会遇到几个activity之间的跳转问题,比如A跳转到B,然后B跳转到C,然后点击C的某一项要回到A,这就存在各种数据传值的问题,今天我们就来掰扯这些activity之间的爱恨情仇。

一、方法简介

android Activity之间的跳转不只是有startActivity(Intent i)的,startActivityForResult(Intent intent, int requestCode)也是常用的方法。在一个主界面(主Activity)上能连接往许多不同子功能模块(子Activity上去),当子模块的事情做完之后就回到主界面,或许还同时返回一些子模块完成的数据交给主Activity处理。这个时候就要用到回调函数onActivityResult()。 需要注意三个方法:

startActivityForResult(Intent intent, int requestCode)onActivityResult(int requestCode, int resultCode, Intent data)setResult(int resultCode, Intent data).

eg: 从From跳转至ToB和ToC

if(条件){ Intent intent = new Intent(this, ToB.class); startActivityForResult(intent, REQUEST_CODE_01);//跳转至ToB }else{ Intent intent = new Intent(this, ToC.class); startActivityForResult(intent, REQUEST_CODE_02);//跳转至ToC } public void onActivityResult(int requestCode, int resultCode, Intent data){ switch (requestCode) {//请求标记 case REQUEST_CODE_01: if(resultCode==Activity.RESULT_OK) //do something break; case REQUEST_CODE_02: //do something break; } }

startActivityForResult(Intent intent, int requestCode)的参数,需要注意的是第二个,我们用的是REQUEST_CODE_01和REQUEST_CODE_02,其实这个是我们自己定义的一个int型常量,用于标记的,具体作用可在onActivityResult方法里看到,用于判断是哪个Activity传来的。 requestCode是请求标记, resultCode是返回标记。

ToB: Intent intent = new Intent(); intent.putExtra(key, value); setResult(Activity.RESULT_OK, intent); finish();//结束之后会将结果传回From

这里的跳转回去,只能用setResult(int resultCode, Intent data)方法,否则会出错,无法从onActivityResult(int requestCode, int resultCode, Intent data)中的data接收到传回来的数据。

ToC: Intent intent = new Intent(); intent.putExtra(key, value); setResult(Activity.RESULT_OK, intent); finish();//结束之后会将结果传回From

setResult的第一个参数对应上面onActivityResult的第二个参数。

二、三个以上的activity之间的跳转传值问题

上面介绍的我相信只要有点Android基础的人都知道,这不是我要讲的重点,我要讲的重点就是开头就说的,A跳转到B,B再跳转到C,然后C要直接回到A,甚至有可能C到D……最后一个再回到A,这种情况下,很多人就会这么干,从最后一个再启动A,可是呢,这样做就会导致A重启,原来的数据会被清空,你可能会说我先做数据保存呗,但你别忘了,有些时候数据并不是那么好保存的,而且需求可能并不是你这样子做就可以满足的。所以我接下来就用上面所说的onActivityREsult跟setResult来实现。那要怎么做呢,其实很简单,一层一层finish呗,看我下面的demo你就会明白了。 demo的大体思路就是MainActivity跳转到FirstActivity.class,然后FirstActivity.class跳转到SecondActivity.class,最后SecondActivity.class再回到MainActivity.class.

(1)MainActivity.class

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } public void pickTestClicked(View view) { gotoFirstActivity(); } private void gotoFirstActivity(){ Intent intent = new Intent(this,FirstActivity.class); startActivityForResult(intent, Const.REQUEST_CODE_FIRST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case Const.REQUEST_CODE_FIRST: if (resultCode == Activity.RESULT_OK) { Log.d("wu", "MainActivity.onActivityResult回调"); Toast.makeText(this, "FirstActivity数据返回", Toast.LENGTH_LONG).show(); } break; } } }

(2)FirstActivity.class

public class FirstActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_activity_layout); } public void firstActivityClick(View view){ gotoSecondActivity(); } private void gotoSecondActivity(){ Intent intent = new Intent(FirstActivity.this,SecondActivity.class); startActivityForResult(intent,Const.REQUEST_CODE_SECOND); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case Const.REQUEST_CODE_SECOND: if (resultCode == Activity.RESULT_OK ) { Log.d("wu", "FirstActivity.onActivityResult回调"); Toast.makeText(this, "SecondActivity数据返回", Toast.LENGTH_LONG).show(); } //这里可以把数据传回去 //比如:Intent intent = new Intent(); //intent.putExtra("data",data); //setResult(RESULT_OK,intent); setResult(RESULT_OK, null); finish(); break; } } }

(3)SecondActivity.class

public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_activity_layout); } public void secondActivityClick(View view){ setResult(RESULT_OK, null); finish(); } }

三、用EventBus的方式传值

通过EventBus传值回A,这时先finish C,然后发一个信息,B收到这个信息也finish,再发一个事件,A收到这个事件后,拿到信息,这样子A的界面也就有内容填充且不会丢失内容。

//搜索版块事件传递 public class SearchResultEvent {    public boolean isStartIssueFromSearch;    public String atName;     public String atId;     public SearchResultEvent(boolean isFromSearch,String atName,String atId ){          isStartIssueFromSearch = isFromSearch;          this.atName=atName;          this.atId=atId;   } } C界面的某一项点击: public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Entity entity = (Entity) parent.getItemAtPosition(position); String atName=""; String atId=""; if (entity instanceof ForumModule) { ForumModule forumModule = (ForumModule) entity; atName=forumModule.getName(); atId=forumModule.getId(); } EventBus.getDefault().post(new SearchResultEvent(true,atName,atId)); EventBus.getDefault().post(new BackFinishEvent(true)); finish(); }

B界面的finish:

public void onEventMainThread(BackFinishEvent event){ if (event.isFinish){ finish(); } }

A界面的更新信息:

public void onEventMainThread(SearchResultEvent event){      if (event.isStartIssueFromSearch){         String atName = event.atName;          String atID = event.atId;          if (mEntity == null) {             ForumModule formuModule = new ForumModule();              formuModule.setId(atID);              formuModule.setName(atName);              formuModule.setChannelName(atName);              mEntity = formuModule;            } else if (mEntity instanceof ForumModule) {                ((ForumModule) mEntity).setName(atName);                 ((ForumModule) mEntity).setId(atID);             }             setCategoryName(mCategoryChose, mEntity);             showKeyboard();         } 这样从C点击某一项就不会导致A界面重启了。
转载请注明原文地址: https://www.6miu.com/read-40292.html

最新回复(0)