Activity的启动跳转与数据传递

一、Activity的启动

1、什么是Intent?

Intent:直译为意图,通俗来说就是你想要做什么或想要去哪?
作用:Intent是Activity、Service和BroadCastReceiver这三个应用组件进行通信的信使。
例如:想要从FirstActivity启动另外一个SecondActivity,就必须使用Intent对象了。


(1)无结果的页面跳转

@Override
   public void onClick(View v) {
       Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
       **startActivity(intent);**
   }

(2)有结果的页面跳转

Activity A跳转到Activity B

public static final int REQUEST_SEARCH = 100;
 
Intent intent = new Intent(getActivity(), MapSearchDeviceActivity.class);
startActivityForResult(intent, REQUEST_SEARCH);
 
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {//判断是否返回成功
            if (requestCode == REQUEST_SEARCH) {//判断来自哪个Activity
                jd = Float.parseFloat(data.getStringExtra("jd"));
                wd = Float.parseFloat(data.getStringExtra("wd"));
            }
        }
    }

Activity B

Intent intent = new Intent();
intent.putExtra("jd", dataBeanList.get(position).getJd());
intent.putExtra("wd", dataBeanList.get(position).getWd());
MapSearchDeviceActivity.this.setResult(RESULT_OK, intent);
MapSearchDeviceActivity.this.finish();

当结果码为RESULT_OK,且请求码为100时,Activity A获取Activity B传过来的intent值。

2、什么是intentFilter?

IntentFilter:意图过滤器,主要用来过滤隐式意图,当用户进行一项操作的时候,Android系统会根据配置的 “意图过滤器” 来寻找可以响应该操作的组件,服务。
作用: IntentFilter通常是定义在AndroidManifest.xml文件中,也可以动态设置,通常是用来声明组件想要接受哪种Intent。例如,你如果为一个Activity设置了IntentFilter,你就可以在应用内或者其他应用中,用特定的隐式Intent来启动这个Activity,如果没有为Activity设置IntentFilter,那么你就只能通过显示Intent来启动这个Activity。

3、显式Intent与隐式Intent的区别

Intent:明确指定目标组件的意图 Intent intent=new Intent(Context context,Class clazz); 当操作当前自己的应用组件时使用。
隐式Intent:没有明确指定目标组件的意图,Intent(String action)当操作其他应用组件时使用
ep:打电话和发短信 都是用的隐式意图。

Intent intentA=new Intent(Intent.ACTION_DIAL);
    //获取号码
    String number=et_main_number.getText().toString().trim();
    //携带号码
    Uri uri = Uri.parse("**tel:**"+number);      //tel是个约束
    intent.setData(uri);
    //需要启动另外一个应用:需要使用隐式意图
    startActivity(intent);


    Intent intentB = new Intent(Intent.ACTION_SENDTO);
    //发短信要有号码,所以获取电话号码,携带着电话号码,再去编辑短信
    //获取号码
    String number = et_main_number.getText().toString().trim();
    Uri uri=Uri.parse("**sms:**"+number);
    //携带号码
    intent.setData(uri);
    //获取短信
    String content = et_main_content.getText().toString();
    //携带短信
    intent.putExtra("**sms_body**", content);
    //启动到另外一个短信界面,需要隐式意图
    startActivity(intent);

3、PendingIntent详解

PendingIntent是一种特殊的Intent,和Intent的区别在于Intent是立刻执行的,而PendingIntent不是,可以被理解为一种异步处理机制。

作用:PendingIntent执行的操作实质上是参数传进来的Intent操作,像通知栏消息的发送就是使用PendingIntent实现。

Intent intent = new Intent(action);  

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT); 

为了提升应用的安全性,Android12要求应用创建的每个PendingIntent对象都要指定可变性, 使用PendingIntent.FLAG_MUTABLE 或PendingIntent.FLAG_IMMUTABLE标志。

如果不设置任一可变性标志, 系统将会抛出IllegalArgumentException异常,报错内容如下:

java.lang.IllegalArgumentException: XXX: Targeting S+ (version 31 and above)
 requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when
 creating a PendingIntent.

二、Activity的关闭与销毁

1、调用finish()方法,用于关闭当前的Activity

2、finish()方法与onDestroy()方法的区别?
finish()属于执行方法,而destroy()属于系统方法。finish()是在程序执行的过程中使用它来将对象销毁,而destroy()方法是在系统将该activity完全销毁(从内存中移除),释放资源空间。在写程序过程中,一般调用finish()。如果我们希望系统释放资源的时候,进行某些操作,则可以重写destroy()方法。

3、onBackProgress()与finish方法的区别?
(1)没有弹框,没有菜单,没有共享变换-----该情况,finish和onBackPressed是完全一样的。
(2)存在弹框、菜单等-----该情况,onBackPressed要先关闭popWindow
(3)存在共享变化-----该情况,finish不会调用变换动画,必须使用onBackPressed方法。

三、如何退出多个Activity

1、在Application中用List保存activity实例,然后逐一干掉

public class MyApplication extends Application {
    private List<Activity> mList = new LinkedList<Activity>();
    private static MyApplication mInstance;

    private MyApplication() {

    }

    public static MyApplication getInstance() {
        if (null == mInstance) {
            synchronized (MyApplication.class) {
                if (null == mInstance) {
                    mInstance = new MyApplication();
                }
            }
        }
        return mInstance;
    }
    //add Activity
    public void addActivity(Activity activity) {
        mList.add(activity);
    }
    public void closeActivity() {
      if(mList!=null){
          for (Activity activity : mList) {
              if (activity != null)
                  activity.finish();
          }
          mList.clear();
      }
    }
}

2、使用注册广播的方式进行关闭Activity

3、使用OnActivityResult递归回调的方式关闭

4、使用setFlags的方式来关闭

(1)使用Intent的FLAG_ACTIVITY_CLEAR_TASK标记,这个标记可以清空要启动的activity所在的task栈。

什么意思呢?假如现在任务栈里面有A、B、C三个activity,这时C启动D,如果加上这个标记,那么启动D的同时就会移除A、B、C,这样这个任务栈里面就只剩新启动的D了。注意:这个标记需要与FLAG_ACTIVITY_NEW_TASK这个配合使用,否则不起作用。

(2)使用Intent的FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK标记,这个标记可以清空要启动的activity上面的所有activity(与新启动的activity同处于一个task栈)。

什么意思呢?假如现在任务栈里面有A、B、 C、 D四个activity,这时D启动A,带上这两个标记,因为A已经在这个task栈中了,这个时候不会启动新的task栈,同时系统发现A的上面有B、C、D,所以系统会将这三个activity从task栈中移除,最终,这个task只剩下A了。


四、回退到指定的Activity

ep:比如我在个人中心页面跳转到A页面,输入完账号之后,到B页面,用户到了B页面,发现A页面的账号输入错误了,要返回,所以我在A跳B的时候就不能将A页面销毁,在B页面的,输入完毕密码之后,跳转到C页面去登录,当然登录完毕之后要回到个人中心页面,但是现在我们的输入账号的A页面还没有销毁,直接finish掉C页面的话会回到A页面.就达不到我们的初衷了.

方式1、

public static FirstActivity instance;

在A页面的onCreate中将当前Activity传入上面定义的静态中,

instance=this;  //在onCreate里面写
我们哪里需要销毁A这个Activity就可以直接在这个Activity中,调用A的静态方法finish就可以了,
现在我们只要在C页面的登录点击事件中调用就可以了。

if(FirstActivity .instance!=null){//给一下判空
       FirstActivity .instance.finish();//在其它的activity里面使用
   }

方式2、

在实际的项目开发中也许会碰到一种情况,需要从A界面跳转到B界面,再从B界面跳转到C界面,再从C界面跳转到D界面,最后需要从D界面跳回到A界面,并且把B、C 、D界面都干掉。也许立马会有人觉得可以在B、C、D界面跳转时就finish()掉当前界面就可以了。但是如果需要在B、C、D界面之间可以正常的返回上一界面,那么在跳转的时候finish()掉当前界面就不合理了。

前面的A界面跳转到B界面,B界面跳转到C界面,C界面跳转到D界面都是正常的跳转,在最后D界面跳回A界面的时候这么写就可以了:

Intent intent = new Intent(D.this,A.class);
   			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
   			startActivity(intent);
   			finish();

这么写就可以从D界面跳回到A界面,并且B、C界面都已经被干掉了。

五、Activity之间传输数据

1、使用Intent的putExtra传递

2、使用Intent的Bundle传递

activity A

Intent intent = new Intent(MainActivity.this,TwoActivity.class);
//创建Bundle对象用来捆绑传递数据
Bundle bundle = new Bundle();
bundle.putString("String数据", str);
bundle.putInt("Int数据",5);
//把Bundle对象通过putExtra()方法放入intent对象中
intent.putExtra("bun", bundle);
//激活TwoActivity
startActivity(intent);

activity B

//获取Bundle对象
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("bun");
//获取数据
String str = bundle.getString("String数据");
int a=bundle.getInt("Int数据")
//设置数据
tv.setText(str);
tv.setText(""+a);

3、使用onActivityResult

4、SharedPreferences传递数据

5、实现了Parcelable的对象及其数组

6、实现了 Serializable 的对象及其数组

import java.io.Serializable;
public class DataBean implements Serializable {
    private String name;
    private int age;
 
    public DataBean() {
    }
 
    public DataBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }

activity A

DataBean ss=new DataBean("carrie",18);
jump_in_item3.putExtra("数据",ss);

activity B 

//反序列化数据对象
Serializable se = intent.getSerializableExtra("数据2");
     if(se instanceof DataBean){
      //获取到携带数据的DataBean对象db
       DataBean db = (DataBean) se;
       tv.setText(db.getName());
       tv.setText(""+db.getAge());
        }

7、使用静态变量传递数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值