美文网首页
Activity Review

Activity Review

作者: Hong2018 | 来源:发表于2017-03-01 10:18 被阅读0次

    Activity Review

    参考资料

    谷歌Activity参考文档

    任务与返回栈, 官方文档的描述

    Activity启动方式和Flag详解

    Activity完全解析

    Activity高级篇:Home键与Back键

    Activity概述

    一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为“主”Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个 Activity 均可启动另一个 Activity,以便执行不同的操作。 每次新 Activity 启动时,前一 Activity 便会停止,但系统会在堆栈(“返回栈”)中保留该 Activity。 当新 Activity 启动时,系统会将其推送到返回栈上,并取得用户焦点。 返回栈遵循基本的“后进先出”堆栈机制,因此,当用户完成当前 Activity 并按“返回”按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。

    启动Activity

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

    隐式意图

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
    startActivity(intent);
    

    Intent 对象的真正价值所在 — 您可以创建一个 Intent 对象,对您想执行的操作进行描述,系统会从其他应用启动相应的 Activity. <参考文档>

    表述:
    如果您想允许用户发送电子邮件,可以创建上面的实例 Intent

    添加到 Intent 中的 EXTRA_EMAIL extra 是一个字符串数组,其中包含应将电子邮件发送到的电子邮件地址。 当电子邮件应用响应此 Intent 时,它会读取 extra 中提供的字符串数组,并将它们放入电子邮件撰写窗体的“收件人”字段。 在这种情况下,电子邮件应用的 Activity 启动,并且当用户完成操作时,您的 Activity 会恢复执行。

    Manifest.xml

    <activity
        android: name="com.alex33.SecondActivity"
        android: icon="@drawable/cat"
        android: label="第二个Activity">
    
        <intent-filter>
            <action android:name="com.alex33.JumpToSecondActiviy"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
    

    SecondActivity.java

    Intent i = new Intent();
    i.setAction("com.alex33.JumpToSecondActivity");
    i.addCategory("android.intent.category.DEFAULT");
    startActivity(intent);
    
    通过隐式意图可以不报楼类文件的情况下, 调用一个Activity

    Activity几种状态

    1. Active(活动 | Active/Runing):当Activity位于栈顶时,它是可见,有焦点的前台Activity,可以用来响应用户的输入。

    2. Paused(暂停 | Paused):一般情况,你的Activity可见但不具有焦点,例如 当前面的Activity是全透明或非透明的Activity时,下面的Activity就位于Paused状态。

    3. Stopped(停止 | Stoped):当一个Activity彻底不可见时,就处于这个状态。此时Activity完全不可见,但在内存中仍旧保留该Activity的状态和成员信息。

    4. Inactive(销毁 | Killed):当一个Activity被杀死时,就变成Inactive。Inactive Activity会从Activity栈中移除,如果重新显示需要重新启动。一般销毁由系统Dalvik控制。

    Activity加载模式

    在android里,有4种activity的启动模式,分别为:

    1. standard: 标准模式,一调用startActivity()方法就会产生一个新的实例。

    2. singleTop: 来了intent, 每次都创建新的实例,仅一个例外:当栈顶的activity 恰恰就是该activity的实例(即需要创建的实例)时,不再创建新实例。这解决了栈顶复用问题。

    3. singleTask: 来了intent后,检查栈中是否存在该activity的实例,如果存在就把intent发送给它,否则就创建一个新的该activity的实例,放入一个新的task栈的栈底。肯定位于一个task的栈底,而且栈中只能有它一个该activity实例,但允许其他activity加入该栈。解决了在一个task中共享一个activity。

    4. singleInstance: 这个跟singleTask基本上是一样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其他的实例。一旦该模式的activity的实例已经存在于某个栈中,任何应用在激活该activity时都会重用该栈中的实例,解决了多个task共享一个activity。
      这些启动模式可以在功能清单文件AndroidManifest.xml中进行设置,中的launchMode属性。

    Activity 生命周期

    Activity生命周期A Activity生命周期OrgActivity生命周期Org

    Activity跳转时的方法回调

    生命周期回调的顺序经过明确定义,当两个 Activity 位于同一进程,并且由一个 Activity 启动另一个 Activity 时,其定义尤其明确。 以下是当 Activity A 启动 Activity B 时一系列操作的发生顺序:

    1. Activity A 的 onPause() 方法执行。
    2. Activity B 的 onCreate()、onStart() 和 onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
    3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

    您可以利用这种可预测的生命周期回调顺序管理从一个 Activity 到另一个 Activity 的信息转变。 例如,如果您必须在第一个 Activity 停止时向数据库写入数据,以便下一个 Activity 能够读取该数据,则应在 onPause() 而不是 onStop() 执行期间向数据库写入数据。

    Manifest.xml的细节

    清单文件中, intent过滤器有MAIN和LAUNCHER, 代表mainActivity的主入口

    <intent-filter>  
        <action android:name = "android.intent.action.MAIN" />
        <category android:name = "android.intent.category.LAUNCHER" />  
    </intent-filter>
    

    使用Bundle在Activity间传值

    Bundle对象有如下方法:

    • putXxx(String key,Xxx data) : 向Bundle中放入int、String等各种类型的数据

    • putSerializable(String key,Serializable data) : 向Bundle中放入可序列化的对象

    • getXxx(String key):取出int、String等各种类型的数据

    • getSerializable(String key):取出可序列化的对象

    当然我们还可以直接调用intent对象的putExtra(String key,Xxx data)方法存入数据,但其本质还是创建或使用了Bundle对象进行传值。

    startActivityForResult的使用

    A-Activity需要在B-Activtiy中执行一些数据操作,跳转至B-Activity后,B-Activity要将执行操作数据的结果返回给A-Activtiy,此时就需要使用 startActivityForResult()来启动B-Activity了。

    使用的三个函数:

    • startActivityForResult (Intent intent, Int requestCode)
    • setResut (int resultCode, Intent intent)
    • onActivityResult (int requestCode, int resultCode, Intent intent)

    Step1.

    在A中跳转的时候不是采用startActivity(intent) 这个方法,而是startActivityForResult(intent, Int requestCode)的形式,requestCode可以是大于等于0的任何值。

    startActivityForResult(intent, 0);

    Step2.

    在A中重写onActivityResult方法,用来接收B回传的数据,因为传回来的resultCode不同而做差别处理。

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        
        switch (resultCode) { //resultCode为回传的标记
            
            case 20:
                Bundle b=data.getExtras(); //data为B中回传的Intent
                String str=b.getString("str1");//str即为回传的值
                break;
    
            default:
                break;
        }
    }
    

    Step3.
    在B中采用setResult方法,并且之后要调用finish方法。

    Intent intent=new Intent();  
    intent.putExtra("str1", str_bookname);  
    setResult(20, data);  
    finish(); //关闭掉这个Activity 
    

    关于A-B Activity切换, Home键, Back键的机制

    任务与返回栈, 官方文档的描述

    Activity 和任务的默认行为总结如下:

    • 当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态(例如,滚动位置和已输入表单中的文本)。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行。

    • 用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。

    • 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统不会保留该 Activity 的状态。
      即使来自其他任务,Activity 也可以多次实例化。

    Home键与Back键对Activity的生命周期影响

    • 如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。

    • 如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。

    由此可见,Back键和Home键主要区别在于是否会执行onDestroy。

    Back键实现Home键效果

    @Override
    public void onBackPressed() {
        Intent home = new Intent(Intent.ACTION_MAIN);
        home.addCategory(Intent.CATEGORY_HOME);
        startActivity(home);
    }
    

    或者

    @Override
    public void onBackPressed() {
         moveTaskToBack(true);
    } 
    

    moveTaskToBack()此方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。

    关于finish()

    1. 将此Activity从Activity栈中移除。
    2. 调用了此Activity的onDestroy方法。

    关于Activity的一些技巧

    锁定为竖屏

    <activity android:name="com.alex33.MainActivity"
        android:label="@string/app_name" 
        android:screenOrientation="portrait">
            // 竖屏为portrait,横屏为landscape
    </activity>
    

    去除标题

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    Android清单文件中MimeType的用途

    Intent-Filter中的有一个mimeType。它的作用是告诉Android系统本Activity可以处理的文件的类型。如设置为 “text/plain”表示可以处理“.txt”文件。

    <intent-filter>
    
        <actionandroid:name="android.intent.action.VIEW" />
    
        <categoryandroid:name="android.intent.category.DEFAULT" />
    
        <data android:mimeType="image/jpeg ">
    
    </intent-filter>
    

    这样就把当前程序注册为可以打开/查看jpeg类型的图片

    当在文件管理器里点击任何jpeg文件, 系统都会试图去执行你的程序。

    " image/jpeg "这一类型属于标准的MIME Type。

    一个简单的隐式跳转并传递值的Demo

    UI

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.goldinfo.sendmessage.MainActivity">
    
        <ListView
            android:id="@+id/ll"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></ListView>
    </RelativeLayout>
    

    item

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="TextView"
        android:id="@+id/textView"
        android:textColor="#123897"
        />
    

    代码实现

    MainActivity

    public class MainActivity extends AppCompatActivity {
    
        private ListView lv;
    
    
        private String[] msgs = {"天气太热了!买了个凉席,一睡变电热毯了!遇到个陌生人,相视一笑,变熟了!桌子太烫,麻将刚码好,嘿,居然糊了!",
                "工作是枯燥的,赚钱是辛苦的,理想却是远大的,等咱有了钱,喝豆浆吃油条,想沾白糖沾白糖,豆浆买两碗,喝一碗,倒一碗!",
                "给你点阳光你就灿烂,给你点洪水你就泛滥。破锅自有破锅盖,丑鬼自有丑女爱,只要情深意似海,麻子也能放光彩!",
                "鸟儿,鸟儿,喳喳叫。清风,清风,去烦恼。祝福,祝福要趁早。短信,短信,恰恰好。朋友,朋友,看到短信笑一笑!",
                "武当派,少林派,不如吃个苹果派;日月教,全真教,不如睡个大懒觉;降龙掌,销魂掌,不如养盆仙人掌;总之,你好我好大家好",
                "我的问候,就是那冰激凌,融在你嘴里,甜在你胃里,爽在你心里。愿你把高温击退,把快乐放飞,生活有滋有味,笑容天天都美!",
                "送你西瓜,爽口爽心顶呱呱;送你电扇,吹走烦躁发发汗;送你清凉油,神清气爽争上游;送你清心茶,伴你天天乐开花!",
                "看事业线,你正走在成功路上;看生命线,你定会健康长寿;看感情线,你桃花运正旺。我的祝福三线合一,愿你快乐无比!",
                "送你五万块,一万健康,一万快乐,一万平安,一万好运,一万幸福,一共五万块红砖。嘿嘿,自己建造个美好城堡吧!",
                "好好活,慢慢过,一年更比一年乐;不要攀,不要比,不要自己气自己;少吃盐,多吃醋,少打麻将多散步。愿你:天天闲里忙着乐!"};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lv = (ListView) findViewById(R.id.ll);
    
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.item, msgs);
    
            lv.setAdapter(adapter);
    
            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
                    //去除点击条目的数据
                    String content = msgs[position];
    
                    //使用隐式意图 跳转到短信页面
                    Intent intent = new Intent();
                    intent.setAction("android.intent.action.SEND");
                    intent.addCategory("android.intent.category.DEFAULT");
                    intent.setType("text/plain");
    
                    //key值需要到android源码中找
                    intent.putExtra("sms_body",content);
    
                    //开启Activity
                    startActivity(intent);
    
    
                }
            });
    
        }
    }

    相关文章

      网友评论

          本文标题:Activity Review

          本文链接:https://www.haomeiwen.com/subject/qwrqgttx.html