Activity Review

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



    
        
        
    

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 Review_第1张图片
Activity生命周期A
Activity Review_第2张图片
Activity生命周期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的主入口

  
    
      

使用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的一些技巧

锁定为竖屏


        // 竖屏为portrait,横屏为landscape

去除标题

requestWindowFeature(Window.FEATURE_NO_TITLE);

Android清单文件中MimeType的用途

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



    

    

    


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

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

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

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

UI

activity_main.xml




    

item



代码实现

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 adapter = new ArrayAdapter(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)