Activity之间传递值

一、通过startActivity来进行Activity的传值

在Android中,如果我们要通过一个Activity来启动另一个Activity,可以使用 startActivity(Intent intent)方法来传入一个Intent对象,这个Intent对象我们可以精确的指定我们需要跳转的Activity上,或者通过Intent对象来指定我们要完成的一个action操作,同时我们可以通过intent来携带一些值,进而来Activity见跳转的时候也可以把值传过去。
  • 通过setClass方法来指定我们要跳转的Activity
[java] view plain copy
  1. Intent intent=new Intent(this,SecondActivity.class);  
  2. intent.putExtra(key,value);  
  3. startActivity(intent);  
  4. //或者  
  5. Intent intent=new Intent();  
  6. intent.setClass(MainActivity.this,SecondActivity.class);  
  7. intent.putExtra(key,value);  
  8. startActivity(intent);  
  • 通过setAction方法来我们要完成的一个action操作
[java] view plain copy
  1. Intent  intent = new Intent();  
  2. intent.setAction("com.example.android_intent.second");  
  3. intent.putExtra(key,value);  
  4. startActivity(intent);  

通过这种方式可以来指定我们的Intent对象要完成某个操作,这个操作可以是启动一个Activity,我们可以在AndroidManifest.xml中在 <Activity> 元素下指定一个 <intent-filter> 对象,然后其子元素声明一个 <action> 元素,这样我们可以将这个action动作绑定到了这个Activity上,即Android操作系统会去找与intent对象中指定的action名字的 <intent-filter>对象,然后执行相应的动作,例如:
[java] view plain copy
  1. <activity   
  2.             android:name="com.example.activitytest.SecondActivity"  
  3.             android:label="SecondActivity">  
  4.             <intent-filter>  
  5.                 <action android:name="com.example.android_intent.second"/>  
  6.                 <category android:name="android.intent.category.DEFAULT"/>  
  7.             </intent-filter>  
  8. </activity>  
这样我们的Intent对象,在启动时,就会找到名字为 com.example.android_intent.second 的<intent-filter>对象,来启动我们的SecondActivity。

我们来看看如何在Activity对象中进行值的传递,也是通过 Intent 对象的各种putExtra方法来进行传递:
MainActivity:
[java] view plain copy
  1. Intent intent=new Intent(this,SecondActivity.class);  
  2.        intent.putExtra("nv_name","小龙女");  
  3.        Bundle bundle=new Bundle();  
  4.        bundle.putString("nan_name","杨过");  
  5.        intent.putExtra("bundle",bundle);  
  6.        startActivity(intent);  
SecondActivity:
[java] view plain copy
  1. Intent intent = getIntent();  
  2.         textView1.setText(intent.getStringExtra("nv_name"));  
  3.         Bundle bundleExtra = intent.getBundleExtra("bundle");  
  4.         textView2.setText(bundleExtra.getString("nan_name"));  
在第二个Activity对象中,可以通过 getIntent() 方法来得到跳转到这个Activity的Intent对象,然后通过 Intent 对象的各种 getXXExtra 方法来得到我们的传过来的值。这样我们就可以实现Activity之间的传值。这里插入一句题外话,Intent传值与Bundle传值有什么区别?区别

二、通过startActivityForResult方法来得到Activity的回传值

在一些情况下,我们通过 A activity跳转到 B activity上,这时希望 A activtiy能从 B activity上得到一些返回值,这个时候我们就不能使用startActivity方法了,而是使用 startActivityForResult方法来完成我们的操作。这样的场景在实际开发中还是很常见的,比如说A activity中做了一个查询的功能,查询向后台请求数据假设需要传入一个时间字段,不传的话默认是当前时间,B activity中可以设置时间,那我们就可以在根据B activity 传回来的时间,在A activity 中就会有不同的查询结果。
下面我们来模拟完成下提的需求:
MainActivity:
[java] view plain copy
  1. package com.example.activitytest;  
  2.   
  3. import android.content.Intent;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.widget.Button;  
  8. import android.widget.TextView;  
  9.   
  10. public class MainActivity extends AppCompatActivity implements View.OnClickListener {  
  11.     private Button button;  
  12.     private TextView textView;  
  13.     private int REQUEST_GET_TIME=0;  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.         button= (Button) findViewById(R.id.btn_click);  
  20.         textView= (TextView) findViewById(R.id.tv_time);  
  21.         button.setOnClickListener(this);  
  22.   
  23.     }  
  24.   
  25.     @Override  
  26.     public void onClick(View view) {  
  27. //        Intent intent=new Intent();  
  28. //        intent.setClass(MainActivity.this,SecondActivity.class);  
  29. //        startActivity(intent);  
  30.         Intent intent=new Intent(this,SecondActivity.class);  
  31.         //第一个参数是Intent对象,第二个requestCode指定我们的一个启动标志值,因为我们可能有多个按钮,如果都是跳转到同一个Activity对象上,  
  32.         //我们需要对其进行标志,才知道是哪个Activity对象跳转过来的。  
  33.         startActivityForResult(intent,REQUEST_GET_TIME);  
  34.     }  
  35.   
  36.     /** 
  37.      * 所有的Activity对象的返回值都是由这个方法来接收 
  38.      * requestCode    If >= 0, this code will be returned in onActivityResult() when the activity exits. 
  39.      * @param requestCode 表示的是启动一个Activity时传过去的requestCode值 
  40.      * @param resultCode 表示的是启动后的Activity回传值时的resultCode值 
  41.      * @param data 表示的是启动后的Activity回传过来的Intent对象 
  42.      */  
  43.     @Override  
  44.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  45.         super.onActivityResult(requestCode, resultCode, data);  
  46.             if(requestCode==REQUEST_GET_TIME&&resultCode==RESULT_OK){  
  47.                 textView.setText(data.getStringExtra("cur_time"));  
  48.             }  
  49.     }  
  50. }  
SecondActivity:
[java] view plain copy
  1. package com.example.activitytest;  
  2.   
  3. import android.content.Intent;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.os.Bundle;  
  6. import android.widget.TextView;  
  7.   
  8. import java.text.SimpleDateFormat;  
  9. import java.util.Date;  
  10.   
  11. public class SecondActivity extends AppCompatActivity {  
  12.     private TextView textView;  
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.activity_second);  
  17.         textView= (TextView) findViewById(R.id.tv_cur_time);  
  18.         String curTime=getCurTime();  
  19.         textView.setText(curTime);  
  20.         Intent intent=new Intent();  
  21.         intent.putExtra("cur_time",curTime);  
  22.         setResult(RESULT_OK,intent);  
  23.         this.finish();  
  24.     }  
  25.   
  26.     private String getCurTime() {  
  27.         long currentTimeMillis = System.currentTimeMillis();  
  28.         SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日 HH:mm");  
  29.         return simpleDateFormat.format(new Date(currentTimeMillis));  
  30.     }  
  31. }  
下面是效果图:

另外需要提到的是,上面都是传一些系统自带的数据类型,如果想传一个对象或者对象的数组怎么办呢?还是可以用Intent传值,不过要对传递的对象作一些特殊处理,可以参考这篇博客:intent可以传递的数据类型

三、先把数据存在本地,然后在下一个Activity中从本地取。

这种方式涉及到数据存储,Android数据的四种持久化存储方式SharedPreferences、SQLite、Content Provider和File,该方式的缺点就是要占用本地的资源,优点是数据可以在多个Activity之间共享。关于这种Activity之间的传值以后会专门写一篇博客介绍,这里先谈下Activity之间传值的几种方式的主线。这里推荐一篇博客,可以大概了解下Android的几种数据存储方式点击打开链接

四、使用EventBus框架

越来越多的项目开发中使用到EventBus这个框架,那什么是EventBus呢?用github开源文档上的介绍就是:一个Android平台的事件总线框架, 它简化了Activity、Fragment、Service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。

开发中我们都知道,很多时候要在Activty与Activty间,Activty与Fragment等之间传递数据进行交互,操作起来很不方便,我们以前可能会用到接口回调,或是用观察者模式来实现,或是发广播等等。这们操作不仅仅代码量大,而且代码耦合性高,性能不佳,也不便于维护。例如:两个Fragment之间的通信你会怎么实现? 按照Android官方给的建议的解决方法如下: Communicating with the Activity,思路就是Activity实现某个接口,然后在Fragment-A关联上Activity之后将Activity强转为接口类型,然后在某个时刻Fragment中回调这个接口,然后再从Activity中调用Fragment-B中方法。这个过程是不是有点复杂呢? 如果你也这么觉得,那也就是你继续看下去的理由了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章