1、Activity

2023-09-09  本文已影响0人  Leo_JiangZhiHao
Activity的显式启动和隐式启动
Activity任务栈是什么

任务栈即存放Activity任务的栈。当我们每打开一个Activity的时候它会就往Activity任务栈中压入一个Activity,当我们每销毁一个Activity的时候它会从Activity任务栈中弹出一个Activity,由于安卓系统自身的设计,我们只能在手机屏幕上获取当前一个Activity的焦点即栈顶元素,其余的Activity会在后台等待系统调用。
任务栈缺点:
1、每开启一次页面都会在任务栈中添加一个Activity,而只有任务栈中的Activity全部清除出栈时,任务栈被销毁,程序才会退出,这样就造成了用户体验差,需要点击多次返回才可以把程序退出了。
2、每开启一次页面都会在任务栈中添加一个Activity还会造成数据冗余,重复数据太多,会导致内存溢出的问题(OOM)。
为了解决任务栈的缺点,故引入了启动模式。

Activity的启动模式和使用场景
Activity的onNewIntent(Intent)方法什么时候会执行
Activity常用的标记位Flags
Activity的生命周期
生命周期
onStart 和 onResume、onPause 和 onStop 的区别

onStart和onStop是从Activity是否可见这个角度来回调的。onResume和onPause是从Activity是否位于前台这个角度来回调的。

Activity A跳转Activity B,再按返回键,生命周期执行的顺序
按home键再返回App、锁屏与解锁屏幕、跳转透明Activity界面再返回、启动一个 Theme 为 Dialog 的 Activity、弹出Dialog时Activity的生命周期
横竖屏切换时Activity的生命周期

分两种情况:
1、不设置Activity的android:configChanges时,横竖屏切换会重新调用各个生命周期默认首先销毁当前activity,然后重新创建加载。
2、设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"时, 横竖屏切换不会销毁Activity,不会执行各项生命周期,回调onConfigurationChanged方法。

系统回收Activity

安卓是通过回收activity的方式来回收内存的。activity处于onPause或者onStop状态时,假如系统资源不足(内存不足),会被系统回收释放。
1、当APP不在前台的时候,资源紧张,强杀APP进程并回收activity,这种情况不会调用生命周期的onDestroy方法。可以用“开发者选项”中的“限制后台进程数”来模拟这种情况。
2、当APP在前台,系统资源不足的时候,会回收APP处于pause或stop状态的Activity,这种情况不杀进程,但会调用onDestroy方法。可以用“开发者选项”中的“不保留活动”打开来模拟这种情况。

Activity的数据是怎么保存的,进程被杀后,保存的数据是怎么恢复的?

在onSaveInstanceState中保存数据,在onCreate或onRestoreInstanceState中恢复。

onSaveInstanceState()、onRestoreInstanceState()的调用时机

onSaveInstanceState方法是只有在系统觉得该Activity存在被系统自动回收的可能性时才会调用。(用户主动销毁Activity不调用,例如按下back键)
总结下,onSaveInstanceState(Bundle outState)会在以下情况被调用:
1、当用户按下HOME键时。
2、从最近应用中选择运行其他的程序时。
3、按下电源按键(锁屏)时。
4、从当前activity启动一个新的activity时。
5、屏幕方向切换时(无论竖屏切横屏还是横屏切竖屏都会调用)。
onRestoreInstanceState()方法只有在activity确实是被系统回收,重新创建activity的情况下才会被调用。
所以在前4种情况下,当前activity的生命周期为:onPause → onSaveInstanceState → onStop
在第5种情况下,当前activity的生命周期为:onPause → onSaveInstanceState → onStop → onDestroy → onCreate → onStart → onRestoreInstanceState → onResume (11版本前可能先调用onSaveInstanceState)

onCreate和onRestoreInstance中恢复数据时的区别
Activity之间传递数据的方式
Activity之间传递数据的方式Intent是否有大小限制,如果传递的数据量偏大,有哪些方案?

有限制,过大会出现crash异常。该异常是TransactionTooLargeException,即传递数据数据过大异常。并且有提到一句话“Parcel objects stored in the Binder transaction buffer”,这表明实际上底层parcel对象在不同activity直接传递过程中保存在一个叫做“Binder transaction buffer”的地方,既然是缓冲区,肯定有大小限制。可以考虑Application、单例、静态类、持久化方法。

scheme协议
String urlStr="http://www.ycbjie.cn:80/yc?id=hello&name=cg";
//url =            protocol + authority(host + port) + path + query
//协议protocol=    http
//域名authority=   www.ycbjie.cn:80
//页面path=          /yc
//参数query=       id=hello&name=cg
//authority =      host + port
//主机host=        www.ycbjie.cn
//端口port=        80

1、AndroidManifest中设置增加拦截器(intent-filter),设置scheme。

<activity
    android:name=".ui.main.ui.activity.SchemeFirstActivity"
    android:screenOrientation="portrait">
    <!--Android 接收外部跳转过滤器-->
    <!--要想在别的App上能成功调起App,必须添加intent过滤器-->
    <intent-filter>
        <!-- 协议部分配置 ,注意需要跟web配置相同-->
        <!--协议部分,随便设置 yc://ycbjie:8888/from?type=yangchong  -->
        <data android:scheme="yc"
            android:host="ycbjie"
            android:path="/from"
            android:port="8888"/>


        <!--下面这几行也必须得设置-->
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <action android:name="android.intent.action.VIEW" />
    </intent-filter>
</activity>

2、在Activity中的重写OnCreate,获取跳转参数。

public class SchemeFirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Uri uri = getIntent().getData();
        if (uri != null) {
            //获取指定参数值
            String type = uri.getQueryParameter("type");
            Log.e("UrlUtils","main: " + type);

            if (type.equals("yangchong")) {
                ActivityUtils.startActivity(GuideActivity.class);
            } else if (type.equals("main")) {
                ActivityUtils.startActivity(MainActivity.class);
            }
        }
        finish();
    }
}

3、调用方式
原生调用:

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("yc://ycbjie:8888/from?type=yangchong"));
startActivity(intent);

网页调用:

<a href="yc://ycbjie:8888/from?type=yangchong">打开叮咚app</a>

4、如何判断一个Scheme是否有效

PackageManager packageManager = getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("yc://ycbjie:8888/from?type=yangchong"));
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isValid = !activities.isEmpty();
if (isValid) {
    startActivity(intent);
}

5、Scheme在短信息中注意要点
设置android:scheme="http"或者android:scheme="https"后,点击短信息或者h5页面,发现没有跳到指定的页面,反而打开的是网页链接。

上一篇 下一篇

猜你喜欢

热点阅读