技海泛舟(个人技术研究)

  • 首页
  • 日积月累
  • 学习计划
  • 随想
  • project
  • 关于
技海泛舟
一个技术宅的博客
  1. 首页
  2. 日积月累
  3. Android
  4. 正文

Android-Activity

2022年10月14日 1008点热度

启停活动页面

  • 启动和结束

    // 从当前页面跳转到新的页面
    startActivity(new Intent(source.this,target.class));
    // eg
    startService(new Intent(MainActivity.this, FloatingButtonService.class));
    // 从当前页面回到上一个页面,相当于关闭当前页面,
    finish(); // 结束当前的活动页面
    
  • 生命周期
    即状态转换的过程

    Activity的七个生命周期方法

    • onCreate:创建活动。把页面布局加载进内存,进入初始状态,这个方法会初始化setContentLayout()方法(屏幕绘制),
    • onStart:开始活动。把活动页面显示在屏幕上。onCreate()方法完成后,此时activity进入了onStart()方法,当前activity是用户可见状态,但是还不能交互,在此可以做一些动画的初始化操作。
    • onResume:恢复活动。onStart()后activity进入onResume方法,当前activity状态属于运行状态,(Running),此时的activity可见可交互。
    • onPause:暂停活动。在系统进行另一个activity是调用,此时通常用于确认对于持久性的数据保存更改,动画的停止以及任何其他可能消耗cpu的内容,该方法执行后,下一个Activity才能开始执行,该方法执行后应该执行onStop()方法,
    • onStop:停止活动。当Activity对于用户不在可见的时候调用,可能是被另一个Activity覆盖,或者退回到桌面,在onStop方法下系统内存紧张时,有可能会被系统回收,
    • onDestory:销毁活动。在Activity被销毁前调用,这是Activity收到的最后调用,当Activity结束或者被系统销毁Activity实例的时候,会被调动该方法,
    • onRestart:重启活动。在Activity被停止后再次启动的时候调用,比如从桌面回到应用中时,然后调用onStart方法().
    • onNewIntent:重用已有的活动实例。(比较特殊的周期过程)
public class Toggle02Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toggle02);
        findViewById(R.id.button01).setOnClickListener(view -> {
//            finish();
            startActivity(new Intent(this,Toggle01Activity.class));
        });

        System.out.println("ActivityA is Create");
    }
    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("ActivityA is start");
    }
    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("ActivityA is Resume");

    }
    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("ActivityA is Pause");
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        System.out.println("ActivityA is restart");
    }
    @Override
    protected void onStop() {
        super.onStop();
        System.out.println("ActivityA is Stop");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("Activity is Destroy");
    }
}
  • 启动模式
    Activity实例,以栈的形式进行存储,也就是所谓的任务栈先进后出。
    主要有2个基本操作:压栈和出栈,其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity。默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示它。当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,手机页面显示的就是前台任务栈中的栈顶元素。

    • 标准模式(standard)

    • 栈顶复用模式(singleTop)

    • 栈内复用模式(singleTask)

    • 单例模式(singleInstance)

    • 启动模式的设置
      启动模式有2种设置方式:1、在AndroidMainifest设置、2、通过Intent设置标志位

    • 在AndroidMainifest设置
      打开AndroidMainifest.xml,给Activity节点添加属性android:launchMode,属性值填入standard表示采取标准模式,默认不添加也是标准模式。

      <activity 
      android:name="com.demo.Main4Activity"
      //通过android:launchMode属性设置
      android:launchMode="singleTask"/>
    • 通过Intent设置标志位

      Intent inten = new Intent (ActivityA.this,ActivityB.class);
      //通过Intent的Flag设置
      // intent.addFlags(Intent,FLAG_ACTIVITY_NEW_TASK);
      intent.setFlags(Intent,FLAG_ACTIVITY_NEW_TASK);
      startActivity(intent);

代码中的启动标志取值说明

intent类的启动标志 说明
FLAG_ACTIVITY_NEW_TASK 指定启动模式为栈内复用模式(SingleTask)。开辟一个新的任务栈。该值类似于standard;不同之处在于,如果原来不存在活动栈,则会创建一个活动栈
FLAG_ACTIVITY_SINGLE_TOP 指定启动模式为栈顶复用模式(SingleTop)。等同于launchMode="singleTop",当栈顶为待转跳的活动实例时,则重用栈顶的实例
FLAG_ACTIVITY_CLEAR_TOP 所有位于其上层的Activity都要移除,SingleTask模式默认具有此标记效果,但singelTask采用onNewIntent方法启动原任务,而它采用先调用onDestroy再调用onCreate来创建任务。当栈中存在待转跳的活动实例时,则重新创建一个新实例,并清除原实例上方的所有实例。
FLAG_ACTIVITY_NO_HISTORY 该标志与standard情况类似,但栈中不保存新的启动的活动实例,下次无论以何种方式再启动该实例,也要走standard模式的完整流程
FLAG_ACTIVITY_CLEAR_TASK 该标志非常暴力,转跳到新页面时,栈中的原有实例都被清空,注意该标志需要结合FLAG_ACTIVITY_NEW_TASK使用,即setFlags方法的参数为"FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_NEW_TASK"

应用实例

  • 不来回跳转页面
    // 创建一个意图对象,准备跳转到指定的活动页面
    Intent intent = new Intent(this,JumpFirstActivity.class);
    // 当栈中存在待转跳的活动实例时,则重新创建该活动的实例,并清除原实例上方的所有实例
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 设置启动标志
    startActivity(intent);  // 转跳到意图指定的活动页面
  • 登录成功后,不再返回登录页面
    // 创建一个意图对象,准备跳转到指定的活动页面
    Intent intent = new Intent(this,LoginSuccessActivity.class);
    // 转跳到新的页面时,栈中的所有实例都被清空,同时开启新任务的活动栈
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); // 设置启动标志
    startActivity(intent);  // 转跳到意图指定的活动页面

在活动页面之间传递消息

  • 显式intent和隐式intent
    显示Intent,直接指定来源活动与目标活动,属于精确匹配。有三种构建方式:
    1 在intent的构造函数中指定

    Intent intent = new Intent(this,ActivityNextActivity.class);
    startActivity(intent); 

    2 调用意图对象的setClass方法指定

    Intent intent = new Intent();
    intent.setClass(this,ActivityNextActivity.class);
    startActivity(intent); 

    3 调用意图对象的setCompoent方法指定

    Intent intent = new Intent();
    ComponentName component = new ComponentName(this,ActivityNextActivity.class);  // 可以指定 包名 活动页名
    intent.setComponent(component);
    startActivity(intent); 
    隐式意图Intent
    没有明确指定要跳转的目标活动,只给出一个动作字符串让系统自动匹配,属于模糊匹配
    常见系统动作的取值说明
    Intent类的系统动作常量名 系统动作的常量值 说明
    ACTION_MAIN android.intent.action.MAIN App启动时的入口
    ACTION_VIEW android.intent.action. VIEW 想用户显示数据
    ACTION_SEND android.intent.action.SEND 分享内容
    ACTION_CALL android.intent.action.CALL 直接拨号
    ACTION_DIAL android.intent.action.DIAL 准备拨号
    ACTION_SENDTO android.intent.action.SENDTO 发送短信
    ACTION_ANSWER android.intent.action.ANSWER 接听电话

示例1调用系统拨号

        String phoneNo = "1234567890";
        Intent intent = new Intent(); // 创建一个新的意图
        intent.setAction(Intent.ACTION_DIAL); // 设置意图动作为准备拨号
        Uri uri = Uri.parse("tel:"+phoneNo); // 声明一个默认的拨号的Uri
        intent.setData(uri); // 设置意图前往的路径
        startActivity(intent); // 启动意图活动页面

示例2发短信

      //        发短信
        String phoneNo = "1234567890";
        Intent intent = new Intent(); // 创建一个新的意图
        intent.setAction(Intent.ACTION_SENDTO); // 设置意图动作为准备发短信
        Uri uri = Uri.parse("smsto:"+phoneNo); // 声明一个发短信的Uri
        intent.setData(uri); // 设置意图前往的路径
        startActivity(intent); // 启动意图活动页面

示例3调到其他app应用

      //        跳到其他app应用
        String phoneNo = "1234567890";
        Intent intent = new Intent(); // 创建一个新的意图
        intent.setAction(android.intent.action.HAHAHAH); // 设置意图动作为调用指定的app活动页名(这个必须要进程中存活的,如果是安装的也能唤醒新的进程)
       intent.addCategory(Intent.CATEGORY_DEFAULT); // 指定调用的app类名
      startActivity(intent); // 启动意图活动页面

在AndroidMainfest.xml里的intent-filter就是配置文件中的过滤器。
其中android.intent.action.MAIN表示App的入口动作,android.intent.category.LAUNCHER表示在桌面上显示App的图标

        
            
                
                
            
            
        
  • 向下一个Activity发送数据
    Intent使用Bundle对象存放待传递的数据信息
    数据类型 读方法 写方法
    整数型 getInt putInt
    浮点数 getFloat putFloat
    双精度数 getDouble putDouble
    布尔值 getBoolean putBoolean
    字符串 getString putString
    字符串数组 getStringArray getStringArray
    字符串列表 getStringList putStringList
    可序列化结构 getSerializable putSerializable

    发送页面

    private TextView tv_send;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_send);
        tv_send = findViewById(R.id.tv_send);
        Button btn_send = findViewById(R.id.btn_send);
        btn_send.setOnClickListener(handler);
    
    }
    
    private View.OnClickListener handler = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_send:
                    //do something
                    Intent intent = new Intent();
                    intent.setClass(IntentSendActivity.this, IntentReceiveMainActivity.class);
                    Bundle bundle = new Bundle();
                    bundle.putString("request_time", Utils.getNowTime());
                    bundle.putString("request_content",tv_send.getText().toString());
                    intent.putExtras(bundle);
                    startActivity(intent);
                    break;
    
            }
        }
    
    };

    接收页面

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_receive_main);
        tv_receive = findViewById(R.id.tv_receive);
    
        Intent intent = new Intent();
        Bundle bundle = getIntent().getExtras();
        String request_time = bundle.getString("request_time");
        String request_content = bundle.getString("request_content");
        String desc = String.format(" 收到请求消息:\n请求事件为%s\n请求内容为%s", request_time, request_content);
        tv_receive.setText(desc);
    
        Button btn_from_receive_to_send = findViewById(R.id.btn_from_receive_to_send);
        btn_from_receive_to_send.setOnClickListener(clickFn);
    
    }
  • 向上一个(返回的)Activity发送数据
    利用回调数据式传值跳转:上一个页面调用startActivityForResult()(已废弃)方法;下一个页面接收并解析请求数据,下一个页面在返回上一个页面时,打包应答数据并调用setResult方法返回数据包;上一个页面重写方法onActivityResult,解析获得下一个页面的返回数据。
    上一个页面

    private TextView tv_send;
    private TextView tv_receive;
    private ActivityResultLauncher register;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_send);
        tv_send = findViewById(R.id.tv_send);
        tv_send.setText("这是发送给其他活动页的数据");
        Button btn_send = findViewById(R.id.btn_send);
        btn_send.setOnClickListener(handler);
    
        tv_receive = findViewById(R.id.tv_receive);
        Button btn_send_and_receive = findViewById(R.id.btn_send_and_receive);
        btn_send_and_receive.setOnClickListener(returnHandler);  
        //            startActivityForResult(intent,6666); // 已要废弃了
        // 注册下一页面返回时使用的回调方法
        register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() {
            @Override
            public void onActivityResult(ActivityResult result) {
    // 取出回调返回的数据
                if (result!=null) {
                    Intent intent =   result.getData();
                    if (intent!=null && result.getResultCode()== Activity.RESULT_OK) {
                        Bundle bundle = intent.getExtras();
                        String response_time= bundle.getString("response_time");
                        String response_content = bundle.getString("response_content");
                        String desc = String.format(" 收到响应消息:\n响应事件为%s\n响应内容为%s", response_time, response_content);
                        tv_receive.setText(desc);
                    }
                }
            }
        });
    }
    
    // 发送带返回函数的数据
    private View.OnClickListener returnHandler = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(IntentSendActivity.this,IntentReceiveMainActivity.class);
            Bundle bundle = new Bundle();
            bundle.putString("request_time",Utils.getNowTime());
            bundle.putString("request_content",tv_send.getText().toString());
            intent.putExtras(bundle);
            //            把返回的消息放在视图上
            register.launch(intent);
        }
    };

    下一个页面

    private TextView tv_receive;
    private TextView tv_receive_to_send;
    private View.OnClickListener clickFn = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_from_receive_to_send:
                    //do something
                    Intent intent = new Intent();
                    intent.setClass(IntentReceiveMainActivity.this, IntentReceiveMainActivity.class);
                    Bundle bundle = new Bundle();
                    bundle.putString("response_time", Utils.getNowTime());
                    bundle.putString("response_content", tv_receive_to_send.getText().toString());
                    intent.putExtras(bundle);
                    setResult(AppCompatActivity.RESULT_OK,intent);
                    finish();
                    break;
    
            }
        }
    
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_receive_main);
        tv_receive = findViewById(R.id.tv_receive);
        tv_receive_to_send = findViewById(R.id.tv_receive_to_send);
    // 获取上一个页面传过来的意图中的数据
        Intent intent = new Intent();
        Bundle bundle = getIntent().getExtras();
        String request_time = bundle.getString("request_time");
        String request_content = bundle.getString("request_content");
        String desc = String.format(" 收到请求消息:\n请求事件为%s\n请求内容为%s", request_time, request_content);
        tv_receive.setText(desc);
    
        Button btn_from_receive_to_send = findViewById(R.id.btn_from_receive_to_send);
        btn_from_receive_to_send.setOnClickListener(clickFn);
    
    }
    • 常用的函数调用方式:调用在下个activity自定义的方法

      // 上一个活动页面调用 下一个页面的函数
      // 方式三:利用下一个页面的函数 传递参数。new 实例一个活动页面,避免 静态修饰
      private View.OnClickListener returnHandler2 = new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          IntentReceiveMainActivity second = new IntentReceiveMainActivity();
          second.receiveActivityActionFn(IntentSendActivity.this, "data_01", "data_02");
      }

      在下一个页面 编写函数,并在onCreate中调用intent

      
      // 方式三:利用自定义函数传递参数时,所使用的函数
           // 方式三 使用函数传递参数时,用来接收上一个页面传递过来的参数
      Intent intent = this.getIntent();
      if (intent != null) {
          String request_time = intent.getStringExtra("parmas_01");
          String request_content = intent.getStringExtra("params_02");
          String desc = String.format(" 收到请求消息:\n请求事件为%s\n请求内容为%s", request_time, request_content);
          System.out.println("数据为:" + desc);
      
          tv_receive.setText(desc);
      }

    }
    ...
    public void receiveActivityActionFn(Context context, String data_01, String data_02) {
    Intent intent = new Intent(context, IntentReceiveMainActivity.class);
    System.out.println("数据为:" + data_01 + ";" + data_02);
    intent.putExtra("parmas_01", data_01);
    intent.putExtra("params_02", data_02);
    context.startActivity(intent);
    }

为活动页面补充附加信息

  • 利用资源文件配置字符串
       // 通过 资源配置文件 读取字符串
        TextView tv_weather = findViewById(R.id.tv_weahter);
        String value = getString(R.string.tv_weather);
        tv_weather.setText(value);
  • 利用元数据传递配置信息
         // 利用 元文件 读取、传递配置信息
        //  例如利用 第三方的sdk:高德地图、微信登录、友盟等等
    //        分三步:1.调用getPackageManager方法获取当前应用的包管理器
    //               2.调用包管理器的getActivityInfo方法获得当前活动页的信息对象
    //              3.活动信息对象的metaData是Bundle包裹类型,调用包裹对象的getString获得指定名称的参数值
        TextView tv_meta =  findViewById(R.id.tv_meta);
        // 从上下文获取包管理器
        PackageManager packageManager = getPackageManager();
        try {
          ActivityInfo info =  packageManager.getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);
            // 获取活动页面附件的元数据
            Bundle bundle = info.metaData;
           String weather =  bundle.getString("weather");
            tv_meta.setText(tv_meta.getText()+":" + weather);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
  • 给应用页面注册快捷方式
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2022年10月24日
< 上一篇
下一篇 >
归档
  • 2024 年 11 月
  • 2024 年 8 月
  • 2024 年 5 月
  • 2024 年 2 月
  • 2023 年 12 月
  • 2023 年 11 月
  • 2023 年 9 月
  • 2023 年 6 月
  • 2022 年 12 月
  • 2022 年 11 月
  • 2022 年 10 月
  • 2022 年 9 月
  • 2022 年 8 月
  • 2022 年 7 月
  • 2022 年 6 月
  • 2022 年 5 月
  • 2022 年 4 月
  • 2022 年 3 月
  • 2022 年 2 月
  • 2022 年 1 月
  • 2021 年 12 月
  • 2021 年 11 月
  • 2021 年 10 月
  • 2021 年 5 月
分类
  • Android
  • Arduino
  • cordova
  • css
  • go
  • html5
  • JavaScript
  • nodejs
  • oracle
  • project
  • system
  • uni-app
  • vscode
  • vue
  • 学习计划
  • 摘抄
  • 随想
最新 热点 随机
最新 热点 随机
windows安装mysql ,VSCODE连接MySQL数据库 创建api的逻辑 观看七战奥运会 德国波尔告别 go utils工具 Go语言中的sort包帮我们实现了对任一类型的数组进行排序。 vue + go安装
jq实现可编辑表格 读阮一峰老师-未来娱乐业 原生js 实现可编辑表格 JavaScript之组成 接站点餐住宿综合管理平台

COPYRIGHT © 技海泛舟(个人技术研究). 2021-2023. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

黑ICP备19002110号-1

黑公网安备 23060202000432号