Android 面试题之Activity干货篇(上)

简介: 1、Activity是什么2、Activity生命周期3、Activity主要的四种状态4、Activity栈(先进后出)5、启动Activity1.简单启动2.数据传递2.1简单数据传递2.2复杂数据传递2.2.1使用数据包Bundle2.2.2使用Serializable(序列化)3.启动带返回值6、Activity的启动模式(launchMode)7、进程的优先级1.前台进程(Foreground process)。2.可见进程(Visible process)。3.服务进程(Service process)。4.后台进程(Background proc

image.png


1、Activity是什么


       Activity是Android四大组件之一,它提供一个界面让用户点击和各种滑动操作,这就是Activity。

微信图片_20220519205643.png



2、Activity生命周期


微信图片_20220519205702.png


      onCreate():你必须实现此回调,它会在系统创建你的 Activity 时触发。你的实现应该初始化Activity的基本组件。


      onStart():此回调包含 Activity 进入前台与用户进行互动之前的最后准备工作。到了这一步用户可见不可交互。


      onResume():此时,该Activity位于Activity堆栈的顶部,并会捕获所有用户输入。应用的大部分核心功能都是在onResume()方法中实现的。到了这一步用户可见可交互。


      onPause():当Activity失去焦点并进入"已暂停"状态时,系统就会调用onPause()。当用户点按"返回"或"最近使用的应用"按钮时,就会出现此状态,这意味着你的Activity仍然部分可见。到了这一步用户可见不可交互。系统会停止动画等消耗CPU的操作。


      onStop():到了这一步用户不可见。停止动画和刷新 UI 等。如果Activity重新与用户互动下一个回调将是onRestart()或Activity彻底终止下一个回调将是onDestroy()。


     onRestart():当处于"已停止"状态的 Activity 即将重启时,系统就会调用此回调。onRestart()会从Activity停止时的状态恢复Activity至运行状态。


      onDestroy():这是Activity最后一个方法。可以用isFinishing()来判断它,如果有dialog在运转,要在这个界面将dialog给cancel掉,不然抛异常。


3、Activity主要的四种状态


image.png

     Running(运行):在屏幕前台(位于当前任务堆栈的顶部)


      Paused(暂停):失去焦点但仍然对用户可见(覆盖Activity可能是透明或未完全遮挡)


      Stopped(停止):完全被另一个Activity覆盖


      Destroyed(销毁):退出,完全销毁


4、Activity栈(先进后出)


image.png


       多个Activity运行时,Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。


5、启动Activity


image.png


1.简单启动


       在AndroidManifest.xml中声明


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scc.demo">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Demo">
        <activity
            android:name=".actvitiy.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.scc.demo.actvitiy.RedActivity"/>
        <activity android:name="com.scc.demo.actvitiy.BlueActivity"/>
    </application>
</manifest>


 在MainActivity.java中启动


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


2.数据传递


2.1简单数据传递


       MainActivity.class


Intent intent = new Intent(MainActivity.this,BlueActivity.class);
intent.putExtra("scc","aiyouyou");
startActivity(intent);


BlueActivity.class


Log.e(getClass().getName(),getIntent().getStringExtra("scc"));

打印结果:aiyouyou


2.2复杂数据传递


2.2.1使用数据包Bundle


       MainActivity.class

Intent intent = new Intent(MainActivity.this,BlueActivity.class);
Bundle bundle = new Bundle();
bundle.putString("scc","heiha");
bundle.putString("size","18");
intent.putExtras(bundle);
startActivity(intent);


BlueActivity.class


Intent intent = getIntent();
Bundle bundle = intent.getExtras();
Log.e(getClass().getName(),bundle.getString("scc")+":"+bundle.getString("size"));


打印结果:heiha:18


2.2.2使用Serializable(序列化)


       创建一个实体类User implements Serializable

       MainActivity.class


Intent intent = new Intent(MainActivity.this,BlueActivity.class);
intent.putExtra("user",new User("帅次","男",20));
startActivity(intent);


 BlueActivity.class


User user = (User)getIntent().getSerializableExtra("user");
Log.e(getClass().getName(),user.getName()+":"+user.getGender()+user.getAge());


 打印结果:帅次:男20


3.启动带返回值


       启动的MainActivity.java


Intent intent = new Intent(MainActivity.this,BlueActivity.class);
intent.putExtra("scc","俺来咧");
startActivityForResult(intent,998);
Log.e(getClass().getName(),"startActivityForResult");


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.e(getClass().getName(),"requestCode:"+requestCode+":resultCode:"+resultCode);
    //启动ActivityCode值998,回传ActivitiyCode值500
    if(requestCode==998&&resultCode==500){
        Log.e(getClass().getName(),"Intent data:"+data.getStringExtra("scc_result"));
    }
}@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.e(getClass().getName(),"requestCode:"+requestCode+":resultCode:"+resultCode);
    //启动ActivityCode值998,回传ActivitiyCode值500
    if(requestCode==998&&resultCode==500){
        Log.e(getClass().getName(),"Intent data:"+data.getStringExtra("scc_result"));
    }
}


被启动的BlueActvitiy.java


Log.e(getClass().getName(),getIntent().getStringExtra("scc"));
btn_back.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.e(getClass().getName(),"onClick.setResult");
        Intent intent = new Intent();
        intent.putExtra("scc_result", "恕瑞玛你们的皇帝回来啦");
        setResult(500, intent);
        finish();
    }
});


  打印结果:


      点击MainActivity启动按钮


       MainActivity$1: startActivityForResult


       BlueActivity: 俺来咧


      点击BlueActvitiy返回按钮


       lueActivity$1: onClick.setResult


       requestCode:998:resultCode:500


       Intent data:恕瑞玛你们的皇帝回来啦


       这就算完事了。


      注意:requestCode不能等于resultCode,否则回传会失效。


6、Activity的启动模式(launchMode)


image.png

standard:每次激活Activity时(startActivity),都创建Activity实例,并放入任务栈;


image.png


singleTop:如果某个Activity自己激活自己,即任务栈栈顶就是该Activity,则不需要创建,其余情况都要创建Activity实例;


image.png


  singleTask:如果要激活的那个Activity在任务栈中存在该实例,则不需要创建,只需要把此Activity放入栈顶。并调用其onNewIntent();


image.png


 singleInstance:应用1的任务栈中创建了MainActivity实例,如果应用2也要激活MainActivity,则不需要创建,两应用共享该Activity实例。


image.png


7、进程的优先级


1.前台进程(Foreground process)。


它表明用户正在与该进程进行交互操作优先级是最高的。Android系统依据下面的条件来将一个进程标记为前台进程:


       1.1、该进程持有一个用户正在与其交互的Activity(也就是这个activity的生命周期方法走到了onResume()方法)。


       1.2、该进程持有一个正在执行生命周期方法(onCreate()、onStart()、onDestroy())的Service。


       1.3、该进程持有一个正在执行onReceive()方法的BroadcastReceiver。


2.可见进程(Visible process)。


它表明虽然该进程没有持有任何前台组件,但是它还是能够影响到用户看得到的界面。android系统依据下面的条件将一个进程标记为可见进程:


       2.1、该进程持有一个非前台Activity,但这个Activity依然能被用户看到(也就是这个Activity调用了onPause()方法)。例如,当一个activity启动了一个对话框,这个activity就被对话框挡在后面。


       1.2、该进程持有一个正在执行方法Service.startForeground()的Service。


3.服务进程(Service process)。


除了符合前台进程和可见进程条件的Service,其它的Service都会被归类为服务进程。


4.后台进程(Background process)。


持有不可见Activity(调用了onStop()方法)的进程即为后台进程。通常情况下都会有很多后台进程,当内存不足的时候,在所有的后台进程里面,会按照LRU(最近使用)规则,优先回收最长时间没有使用过的进程。


5.空进程(Empty process)。


不持有任何活动组件的进程。保持这种进程只有一个目的,就是为了缓存,以便下一次启动该进程中的组件时能够更快响应。当资源紧张的时候,系统会平衡进程缓存和底层的内核缓存情况进行回收。


       5.1.这些进程通常包含用户当前不可见的一个或多个Activity实例(onStop()方法已被调用并返回)。


相关文章
|
7小时前
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
46 1
|
7小时前
|
数据库 Android开发 开发者
Android基础知识:请解释Activity的生命周期。
Android基础知识:请解释Activity的生命周期。
47 2
|
8月前
|
XML Java Android开发
Android面试官最喜欢问15道面试题
Android面试官最喜欢问15道面试题
104 0
|
7月前
|
存储 SQL 人工智能
Android Activity启动流程一:从Intent到Activity创建
Android Activity启动流程一:从Intent到Activity创建
|
7小时前
|
XML Java Android开发
利用Bundle实现Android Activity间消息的传递
利用Bundle实现Android Activity间消息的传递
11 2
|
7小时前
|
Android开发 数据库管理
Android如何在Activity和Service之间传递数据
Android如何在Activity和Service之间传递数据
11 3
|
7小时前
|
Shell Android开发
Android Activity重写dump方法实现通过adb调试代码
Android Activity重写dump方法实现通过adb调试代码
13 0
|
7小时前
|
Java Android开发
Android四大组件之Activity组件
Android四大组件之Activity组件
|
7小时前
|
存储 算法 Java
Android面试题大全
Android面试题大全
15 1
|
7小时前
|
存储 安全 Java
Android 面试题及答案整理,最新面试题
Android 面试题及答案整理,最新面试题
93 2