Activity利用Intent传递数据

一、从父Activity启动子Activity并传递数据

     Intent的中文意思是“意图,目的”的意思,可以理解为不同组件之间通信的“媒介”或者“信使”。 Intent由以下几个部分组成:动作(action),数据(data),分类(Category),类型(Type),组件(Component),和扩展信息(Extra)。

      Intent应该算是Android中特有的东西。你可以在Intent中指定程序要执行的动作(比如:view,edit,dial),以及程序执行到该动作时所需要的资料。都指定好后,只要调用startActivity(),Android系统会自动寻找最符合你指定要求的应用程序,并执行该程序。

     四大组件中的Activity、Services、BroadCastProvider都是通过Intent传递数据。

     Activity 的 Intent 用到的 Action 主要有以下几种:

android.intent.action.MAIN   应用程序入口 
android.intent.action.VIEW  显示数据给用户 
android.intent.action.DIAL  直接打电话  
android.intent.action.SEND  直接发短信 
android.intent.action.RUN  运行数据
android.intent.action.SEARCH  搜索

       在本例中,父Activity:BasicActivity     子Activity:SubActivity

(1) 显式Intent

   1、在BasicActivity中启动SubActivity,并携带信息

BasicActivity.java


//用Intent绑定两个Activity
Intent intent = new Intent(BasicActivity.this,SubActivity.class);
intent.putExtra("data_tag","hello sub activity");//用Extra携带信息
startActivity(intent);//从BasicActivity启动SubActivity

  2、从SubActivity中读取上面来自BasicActivity的信息

         利用标签 "data_tag"传递数据。

SubActivity.java

Intent intent = getIntent();
String msg = intent.getStringExtra("data_tag");//从intent中读取信息
Log.d(TAG,"msg from parent: " + msg);

  显式Intent 是通过BasicActivity.this对象和SubActivity.class来将两个Activity关联起来的。

(2) 隐式Intent

     1、 隐式Intent需要去AndroidManifest.xml文件中对Intent进行配置,注册SubActivity并定义intent-filter的Action(行为)和Category(种类)对intent进行过滤,只有一个intent的action和category都匹配,才能启动这个Activity。

<activity android:name=".SubActivity">
      <intent-filter>
           <!-- 下述定义用于隐式intent,自定义了action和category -->
           <action android:name="com.example.yy.ACTION_START_SUB"/>
           <category android:name="com.example.yy.MY_CATEGORY"/>
      </intent-filter>
</activity>

然后在BasicActivity中以下列方式创建Intent并用其启动intent,系统会进行action和category的匹配,最后选择启动SubActivity,因为SubActivity中的action和category与这个intent完全匹配。

BasicActivity.java

//利用xml中的配置信息关联BasicActivity和SubActivity
Intent intent = new Intent("com.example.yy.ACTION_START_SUB");
intent.addCategory("com.example.yy.MY_CATEGORY");
intent.putExtra("data_tag","hello sub activity");//用Extra携带信息
startActivity(intent);

   隐式Intent 是通过xml文件中的配置将两个Activity关联起来的。

2、从SubActivity中读取上面来自BasicActivity的信息

         接收信息与显式Intent相同

SubActivity.java

Intent intent = getIntent();
String msg = intent.getStringExtra("data_tag");//从intent中读取信息
Log.d(TAG,"msg from parent: " + msg);

(3) 其他隐式Intent

         想在app中展示网页的时候,可以用下列方式,app会调用操作系统的浏览器去访问指定网页,系统浏览器中的intent-filter的action就是Intent.ACTION_VIEW。

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
intent.putExtra("extra","subActivity");
startActivity(intent);

如果自定义一个Activity,让其intent-filter的action也为Intent.ACTION_VIEW,那么启动该intent的时候,就会同时匹配系统浏览器和自定义的这个Activity,系统会弹出选择框,让用户选择打开方式。

二、子Activity被启动后如何返回数据给父Activity

        1、 首先,要想让子Activity被启动之后能够反馈数据给父Activity,那么父Activity在启动子Activity的时候,必须使用startActivityForResult()方法,而不是前面的startActivity()方法。将前面的startActivity(intent)替换成下列代码即可:

BasicActivity.java

startActivityForResult(intent,REQUEST_CODE_SUB);
//REQUEST_CODE_SUB是一个整型常量,是一个与子Activity通信的标识

        2、 同时,在接收端SubActivity也需要有一定的修改,SubActivity不仅要接收来自BasicActivity的数据,还要反馈数据给BasicActivity:

SubActivity.java

//在SubActivity中创建一个Intent,并绑定反馈信息
Intent intent = new Intent();
intent.putExtra("data_return_tag","the echoed message");
//设置ResultCode,成功就是RESULT_OK,失败就是RESULT_CANCELED
setResult(RESULT_OK,intent);
//终止SubActivity
finish();

    3、最后,BasicActivity必须在 onActivityResult()方法 中接收来自SubActivity的反馈数据

      在BasicActivity中重写onActivityResult()方法,添加接收反馈数据的逻辑:

BasicActivity.java


@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case REQUEST_CODE_SUB:
                if (resultCode == RESULT_OK){
                    String msgFromSub = data.getStringExtra("data_return_tag");
                    Log.d("Basic","msg echoed from sub: " + msgFromSub);
                }
                break;
            default:
        }
}

 三、返回栈

       Android中的Activity是可以层叠的,每启动一个新的Activity,它会叠放在父Activity之上,是以栈的形式存放Activity,每个栈由一个Task去管理,用户点击back按钮的时候会销毁栈顶的Activity,下面的那个Activity就会显示出来。

       Activity的状态有下面几种:

 (1) 运行

       处于栈顶的Activity是运行状体,系统不会轻易清理运行时的Activity

 (2) 暂停

       不处于栈顶但是仍然可见的Activity处于暂停状态,如对话框形式的DialogActivity,当MainActivity启动一个DialogActivity后,MainActivity虽然不在栈顶,但是依然可见(没有被DialogActivity完全挡住),只有在内存极低的情况下,系统才会去清理这种状态的Activity

 (3) 停止

      Activity不处于栈顶,并且完全不可见,那么它就处于停止状态,虽然系统会为它们保存状态和成员变量,但是这并不靠谱,它们随时会被系统回收

 (4) 销毁

      当一个Activity从栈中移除后,就处于销毁状态,系统最倾向于将它们回收

 

四、Activity的生命周期方法

onCreate()
      activity在第一次被创建的时候调用,该方法中通常完成一些初始化操作,如加载布局和绑定事件等

onStart()
      当Activity从不可见变为可见的时候调用

onResume()
      当activity处于运行状态的时候调用,这时activity位于栈顶

onPause()
      当系统准备启动或者回复另一个Activity的时候调用,通常在该方法中释放一些资源和保存关键数据。

onStop()
      当Activity变得完全不可见的时候调用

onDestroy()
      当Activity被销毁之前调用,调用之后,Activity就被销毁了

onRestart()
      当Activity从停止状态变为运行状态的时刻调用,也就是Activity被重新启动了

完整生存期 onCreate()和onDestroy()

       这两个方法之间是Activity的完整生命期,从onCreate()创建,从onDestroy()销毁


可见生存期 onStart()和onStop()

      这两个方法之间是Activity的可见时间,在这段时间,Activity虽然可能与用户无法交互,但是对用户是可见的。我们可以通过这两个方法合理地管理用户可见的资源。通常在onStart中对资源进行加载,在onStop中对资源进行释放。


前台生存期 onResume()和onPause()

      这两个方法之间是Activity的前台生存期,在这段时间,Activity是可见的,并且可以与用户交互。

 

五、Activity的启动模式

1、standard

                           

          这种模式下,如果多次启动FirstActivity,栈中就会出现三个FirstActivity,要想退出应用,得按下3次back才行。

2、singleTop

                    

     这种模式下,可以解决重复创建栈顶Activity的问题,如果连续创建两个FirstActivity,那么只会产生一个。但是如果中间隔了一个SecondActivity,那么再次启动的FirstActivity就又会是新的,换句话说,这种模式只会保证栈顶Activity的创建不会重复

3、singleTask

                            

     这种模式下,可以保证每种Activity只会创建一次。

4、singleInstance

                     

          这种模式下,会使用两个返回栈,假设我们要实现当前app和其他app共享某个Activity,就必须用这种模式,在SecondActivity的注册代码中加上启动模式:

android:launchMode="singleInstance"

           这样的话,secondActivity启动之后就会被放在第二个返回栈里面,它的taskId是不同于其他两个的。

六、Activity被回收之后,数据怎么保存( onSaveInstanceState() )

         假设现在有一个Activity A,用户在A的基础上启动了Activity B,那么A就进入了停止状态,如果这时系统内存不足,就会将A回收掉,那么用户按下back键返回A,会出现什么情况呢?答案是执行A的onCreate()方法,而不是onRestart()

         在这种情况下,就必须利用 onSaveInstanceState()方法 保存好A之前的数据,onSaveInstanceState()方法会携带一个Bundle类型的参数,bundle可以用putString、putInt等方法保存数据。

         利用这个方法将数据保存之后,Activity A下次通过onCreate()方法启动的时候,就会从Bundle中取出数据,从而防止数据丢失

 

七、一些Activity相关技巧

1、启动子Activity的最佳方式

       在子Activity中定义一个activityStart()方法,然后在BasicActivity利用类名调用即可启动子Activity。 

SubActivity.java

public static void actionStart(Context context , String data , int requestCode){
	Intent intent = new Intent(context,SubActivity.class);
 	intent.putExtra("param1",data);
	context.startActivityForResult(intent,requestCode);
}


BasicActivity.java

SubActivity.actionStart(BasicActivity.this,"message",requestCode);

 

2、自定义Activity管理器来管理Activity

public class ActivityManager{
	public static List<Activity> activities = new ArrayList<>();
	
	public static void addActivity(Activity activity){
		activities.add(activity);
	}

	public static void removeActivity(Activity activity){
		activities.remove(activity);
	}

	public static void finishAll(){
		for(Activity activity : activities){
			if(!activity.isFinishing()){
				activity.finish();
			}
		}
	}
}

如果想在某个时刻直接退出app,而不是慢慢的去销毁栈中的所有Activity,就可以直接调用finishAll()方法。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值