Android复习——Activity

前言

1.activity是什么:是一个与用户交互,包含多个用户界面的组件。

2.特点:
1.继承特定的类,实现特定的接口
2.配置文件中配置全类名
3.对象是系统创建的不是new出来的
4.对象具有生命周期,类有生命周期的回调方法
3.哪些地方用到反射(全类名):
1.配置文本中配置全类名
2.布局文件定义
3.显式意图

Intent

1.activity是什么:是一个与用户交互,包含多个用户界面的组件。

2.intent的使用,显式隐式:

public class MainActivity extends AppCompatActivity {
    private static final int GO_SECOND = 1;
    private Button btn_main;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_main = findViewById(R.id.btn_main);
        btn_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //显:没别的了,就这一句,意图极其明显
               // Intent i = new Intent(MainActivity.this,SecondActivity.class);
 
                //隐: 1.自定义action,manifest那要改
                    //<action android:name="com.example.fourcomponents.secondactivity"/>
                //Intent i = new Intent("com.example.fourcomponents.secondactivity");
 
                //隐: 2.自定义category.匹配action可以匹配上之后,如果add这个匹配不上就报错了
//                <action android:name="com.example.fourcomponents.secondactivity"/>
//                <category android:name="android.intent.category.DEFAULT"/>
//                <category android:name="com.example.fourcomponents"/>
                /*Intent i = new Intent("com.example.fourcomponents.secondactivity");
                i.addCategory("com.example.fourcomponents");
                startActivity(i);*/
 
                //隐:3. android的action,重点setData
                // new Intent里面是大动作,ps上网,打电话,setdata是去哪个页面,打什么号码
//                Intent i = new Intent(Intent.ACTION_DIAL);
//                i.setData(Uri.parse("tel:10086"));
 
                //隐:4. android的action,重点setData,manifest里面写data,data必须符合setdata才能正常运行
                //<data android:scheme="http"/>
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse("http://www.baidu.com"));
 
                //传递数据act1---》act2:
                /*Intent i = new Intent(MainActivity.this,SecondActivity.class);
                i.putExtra("chuangei2de","woshi1111");//key,value
                */
 
                //传递数据act1《---act2:
                /*Intent i = new Intent(MainActivity.this,SecondActivity.class);
                startActivityForResult(i,GO_SECOND);*/
            }
        });
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case GO_SECOND:{//转为act2时
                if(resultCode == RESULT_OK){//act2传递回act1正确时
                    String s = data.getStringExtra("2chuangei1");
                    Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();
                }
                break;
            }
            default:
                break;
        }
    }
}
 
public class SecondActivity extends AppCompatActivity {
    private Button btn_sec;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        btn_sec = findViewById(R.id.btn_sec);
        btn_sec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //传递数据1---》2:
                /*Intent i = getIntent();
                String s = i.getStringExtra("chuangei2de");
                Toast.makeText(SecondActivity.this,s,Toast.LENGTH_SHORT).show();*/
 
                //传递数据1《---2:
                Intent data = new Intent();
                data.putExtra("2chuangei1","woshi2chuanlaide");
                setResult(RESULT_OK,data);
                finish();//第一次就忘记写了
            }
        });
    }
 
    @Override
    public void onBackPressed() {
        //传递数据1《---2:
        super.onBackPressed();
        Intent data = new Intent();
        data.putExtra("2chuangei1","woshi2chuanlaide");
        setResult(RESULT_OK,data);
        finish();//第一次就忘记写了
    }
}
 
<activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="Intent.ACTION_VIEW)"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.example.fourcomponents"/>
                <data android:scheme="http"/>
            </intent-filter>
 </activity>
 

生命周期与生存期

在这里插入图片描述

活动被回收了几种情况:
1.活动1被销毁了:1启动了2,因为内存不够1被释放了,当2back时候,1是从create生命周期开始的。

2.有临时数据:bundle,或者intent。
1.bundle:oncreate中读取,onSaveInstanceState()中存。

//MainActivity中
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null){
            String s = savedInstanceState.getString("key");
            Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();
        }
…
}
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key","value");
    }

2.intent+bundle:使用putextra:

btn_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this,SecondActivity.class);
                Bundle extra = new Bundle();
                extra.putString("key","value");
                i.putExtra("name",extra);
                startActivityForResult(i,GO_SECOND);
}
}
//main中
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case GO_SECOND:{
                if(resultCode == RESULT_OK){
                    //String s = data.getStringExtra("key");
                    Bundle bundle = data.getBundleExtra("name");
                    String s = bundle.getString("key");
                    Log.d("first", s.toString());
                }
                break;
            }
            default:
                break;
        }
    }
 
btn_sec.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = getIntent();
                Bundle bundle = i.getBundleExtra("name");
                String s = bundle.getString("key");
                setResult(RESULT_OK,i);
                Log.d("sec", s.toString());
                finish();
}
}

特殊运行情况:
1.死亡—运行:create-start-resume
2.运行—死亡:pause-stop-destory
3.运行—停止:pause-stop
4.停止—运行:restart-start-resume
5.运行—暂停:pause
6.暂停—运行:resume

活动的启动模式

1.standard:标准模式,都会为新启动的活动,新建一个实例,采用后进先出的出站模式,
2.singleTop:如果新入栈的活动是已经存在栈顶的,那么这个活动不会产生新的实例。
3.singleTask:如果新入栈的活动是存在在栈中的,会将栈中此活动所在的栈帧之上的栈帧全部出栈,该活动则作为栈顶活动。
4.singleInstance:如果栈顶的活动是这个启动模式,在新活动入栈时,会将自身出栈到一个只存在自身活动的独立的返回栈,通过自身启动的别的活动将进入原来的返回栈。
在这里插入图片描述

在这里插入图片描述

面试题

1.什么是 Activity?
Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供,BroadcastReceiver广播接收器)之一。

Activity是一个应用程序组件,提供一个屏幕可以显示一些控件,用户可以为了完成某项任务用来交互并且对事件做出响应并且通过Intent在Activity之间进行通信。

Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。

2.请描述一下 Activity 生命周期:
1.启动Activity:onCreate方法,onStart方法,最后调用onResume,Activity进入运行状态。

2.当前Activity被其他Activity覆盖其上或被锁屏:onPause方法,暂停当前Activity的执行。

3.当前Activity由被覆盖状态回到前台或解锁屏:onResume方法,再次进入运行状态。

4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:onPause方法,然后onStop方法,进入停止状态。

5.用户后退回到此Activity:onRestart方法,然后onStart方法,最后onResume方法,再次进入运行状态。

6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。

7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。

Activity 从创建到销毁有多种状态,从一种状态到另一种状态时会激发相应的回调方法,这些回调方法包括:onCreate onStart onResume onPause onStop onDestroy其实这些方法都是两两对应的,onCreate 创建与 onDestroy 销毁;onStart 可见与 onStop 不可见;onResume 可编辑(即焦点)与 onPause;/常 见 的 Activity 类 型 有 FragmentActivitiy,ListActivity ,TabAcitivty 等。/

3.如何保存 Activity 的状态(保存额外的数据)?
详情P2的 活动被回收了怎么办
onSaveInstanceState() 方 法

Activity 的状态通常情况下系统会自动保存的,只有当我们需要保存额外的数据时才需要使用到这样的功能。一般来说, 调用 onPause()和 onStop()方法后的 activity 实例仍然存在于内存中, activity 的所有信息和状态数据不会消失, 当 activity 重新回到前台之后, 所有的改变都会得到保留。但是当系统内存不足时, 调用 onPause()和 onStop()方法后的 activity 可能会被系统摧毁, 此时内存中就不会存有该 activity 的实例对象了。如果之后这个 activity 重新回到前台, 之前所作的改变就会消失。为了避免此种情况发生 , 我 们 可 以 覆 写 onSaveInstanceState() 方 法 。onSaveInstanceState()方法接受一个 Bundle 类型的参数, 开发者可以将状态数据存储到这个Bundle 对象中, 这样即使 activity 被系统摧毁, 当用户重新启动这个 activity 而调用它的 onCreate()方法时, 上述的 Bundle 对象会作为实参传递给 onCreate()方法, 开发者可以从 Bundle 对象中取出保存的数据, 然后利用这些数据将 activity 恢复到被摧毁之前的状态。需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下 BACK 键退出 activity 时, 用户显然想要关闭这个 activity, 此时是没有必要 保 存 数 据 以 供 下 次 恢 复 的 , 也 就 是 onSaveInstanceState() 方 法 不 会 被 调 用 . 如 果 调 用onSaveInstanceState()方法, 调用将发生在 onPause()或 onStop()方法之前。

@Override

protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}

3.两个 Activity 之间跳转时必然会执行的是哪几个方法?

一般情况下比如说有两个activity,分别叫A,B,当在A里面激活B组件的时候, A会调用 onPause()方法,然后 B 调用 onCreate() ,onStart(), onResume()。
这个时候 B 覆盖了窗体, A 会调用 onStop()方法. 如果 B 是个透明的,或者是对话框的样式, 就不会调用 A 的 onStop()方法。

4.横竖屏切换时 Activity 的生命周期:
此时的生命周期跟清单文件里的配置有关系。
1.不设置 Activity 的 android:configChanges 时,切屏会重新调用各个生命周期默认首先销毁当前 activity,然后重新加载。
2.设置 Activity android:configChanges="orientation|keyboardHidden|screenSize"时,切屏不会重新调用各个生命周期,只会执行 onConfigurationChanged 方法。通常在游戏开发, 屏幕的朝向都是写死的。

5.如何将一个 Activity 设置成窗口的样式
只需要给我们的 Activity 配置如下属性即可。android:theme="@android:style/Theme.Dialog"

6.如何退出Activity?如何安全退出已调用多个Activity 的Application?
自己补充:自己建一个ActivityCollector类(管理所有act)和一个BaseApplication类继承appcompatact(为了获取有哪些类),然后BaseApplication重写oncreate(里面用ActivityCollector的addactivity方法),重写ondestory(里面用ActivityCollector的removeact方法),每一个类实现BaseApplication,想要退出时直接用ActivityCollector.removeact(this) 或者ActivityCollector.finshall。

(1)通常情况用户退出一个 Activity 只需按返回键,我们写代码想退出 activity 直接调用 finish()方法就行。

(2)记录打开的 Activity:每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。
//比较像我自己补充的ActivityCollector里面的代码
//伪代码

List<Activity> lists ;// 在 application 全局的变量里面
lists = new ArrayList<Activity>();
lists.add(this);
for(Activity activity: lists)
{
activity.finish();
}
lists.remove(this);

(3)发送特定广播:

在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭即可。

//给某个 activity 注册接受接受广播的意图
registerReceiver(receiver, filter)
//如果过接受到的是 关闭 activity 的广播 就调用 finish()方法 把当前的 activity finish()掉

(4)递归退出

在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在 onActivityResult 中处理,递归关闭。

(5)其实也可以通过 intent 的 flag 来实现 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一个新的 activity。此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有 Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。

7.Activity 的四种启动模式,singletop 和 singletask 区别是什么?一般书签的使用模式是 singletop,那为什么不使用 singletask?
singletask不会创建相同活动的实例,singletop不位于栈顶的时候会
singleTop 跟 standard 模式比较类似。唯一的区别就是,当跳转的对象是位于栈顶的 activity(应该可以理解为用户眼前所 看到的 activity)时,程序将不会生成一个新的 activity 实例,而是直接跳到现存于栈顶的那个 activity 实例。拿上面的例子来说,当 Act1 为 singleTop 模式时,执行跳转后栈里面依旧只有一个实例,如果现在按返回键程序将直接退出。singleTask 模式和 singleInstance 模式都是只创建一个实例的。在这种模式下,无论跳转的对象是不是位于栈顶的 activity,程序都不会生成一个新的实例(当然前提是栈里面已经有这个实例)。这种模式相当有用,在以后的多 activity 开发中,常会因为跳转的关系导致同个页面生成多个实例,这个在用户体验上始终有点不好,而如果你将对应的 activity 声明为 singleTask 模式,这种问题将不复存在。在主页的 Activity 很常用

8.Android 中的 Context, Activity,Appliction 有什么区别?
相同:Activity 和 Application 都是 Context 的子类。Context 从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。
不同:维护的生命周期不同。 Context 维护的是当前的 Activity 的生命周期,Application 维护
的是整个项目的生命周期。使用 context 的时候,小心内存泄露,防止内存泄露,注意一下几个方面:

  1. 不要让生命周期长的对象引用 activity,context,即保证引用 activity 的对象要与 activity 本身生命周期是一样的。
  2. 对于生命周期长的对象,可以使用 application,context。
  3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化。

9.两个 Activity 之间传递数据,除了 intent,广播接收者,contentprovider 还有啥?
1)利用 static 静态数据,public static 成员变量
2)利用外部存储的传输,
例如 File 文件存储
SharedPreferences 首选项
Sqlite 数据库

10.Context 是什么?
1、它描述的是一个应用程序环境的信息,即上下文。
2、该类是一个抽象(abstract class)类,Android 提供了该抽象类的具体实现类(ContextIml)。
3、 通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如: 启动一个 Activity,发送广播,接受 Intent,信息,等。
活动的保存

//MainActivity中
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null){
            String s = savedInstanceState.getString("key");
            Toast.makeText(MainActivity.this,s,Toast.LENGTH_SHORT).show();
        }
…
}
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key","value");
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值