Android知识点总结(复习)

  1. Kotlin 数据类型? var val? 函数定义 fun? Kotlin 继承? when 表达式?
  1. Kotlin 数据类型:

    基本数据类型包括:

    • 整数类型:Byte、Short、Int、Long
    • 浮点数类型:Float、Double
    • 字符类型:Char
    • 布尔类型:Boolean

    引用数据类型包括:

    • 字符串类型:String
    • 数组类型:Array
    • 集合类型:List、Set、Map
  2. var val?

    var 为变量

    val 为常量

  3. 函数定义 fun?

    在 Kotlin 中,函数可以使用 fun 关键字进行定义。

    函数定义的基本语法如下:

    1
    2
    3
    4
    fun 函数名(参数列表): 返回值类型 {
    // 函数体
    return 返回值
    }

    其中,参数列表和返回值类型都可以省略。如果函数没有返回值,可以将返回值类型指定为 Unit 或者省略不写。

    以下是一个简单的例子:

    1
    2
    3
    fun add(a: Int, b: Int): Int {
    return a + b
    }

    这个函数的名称是 add,接受两个整数参数 ab,返回它们的和。

  4. Kotlin 继承?

    Kotlin 支持继承,使用 : 符号来实现。

    下面是一个简单的示例,展示了如何在 Kotlin 中定义一个继承自另一个类的子类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 父类
    open class Animal(val name: String) {
    fun sleep() {
    println("$name is sleeping")
    }
    }

    // 子类
    class Cat(name: String) : Animal(name) {
    fun meow() {
    println("$name is meowing")
    }
    }

    在这个示例中,Animal 类是一个基类,它有一个名为 name 的属性和一个名为 sleep 的方法。Cat 类是一个子类,它继承了 Animal 类,并添加了一个名为 meow 的方法。

    注意,在 Kotlin 中,如果你想让一个类可以被继承,需要使用 open 关键字来标记该类。默认情况下,Kotlin 中的类都是不可继承的。

  5. when 表达式?

    when是Kotlin中的一个控制流语句,用作Java中switch语句的替代品。它允许您检查变量是否与多个可能的值匹配,并根据匹配的值执行不同的代码块。

    以下是Kotlin中when表达式的示例:

    1
    2
    3
    4
    5
    6
    7
    val x = 2
    when (x) {
    1 -> println("x is 1")
    2 -> println("x is 2")
    3 -> println("x is 3")
    else -> println("x is not 1, 2, or 3")
    }

    在此示例中,使用when表达式检查了变量x与三个可能的值是否匹配。如果x匹配任何一个值,则执行相应的代码块。如果x不匹配任何值,则执行else代码块。

  1. Android 系统框架层分类?

    Android系统框架层可以分为以下几个主要类别:

    1. 应用程序框架层:这个层次包括了应用程序开发所需的所有基础设施,例如Activity Manager、Window Manager、View System、Package Manager等。
    2. 系统运行时库层:这个层次提供了Android系统的核心功能,例如Dalvik虚拟机、Android运行时库、核心库等。
    3. 系统资源管理器层:这个层次提供了Android系统的资源管理器,例如资源管理器、通知管理器、位置管理器等。
    4. 硬件抽象层:这个层次提供了Android系统与硬件之间的接口,例如相机、蓝牙、Wi-Fi等。
    5. 内核驱动程序层:这个层次包括了Android系统的内核驱动程序,例如显示驱动程序、音频驱动程序、输入驱动程序等。

    这些层次共同构成了Android系统框架层,每个层次都提供了不同的功能和服务,以支持Android应用程序的开发和运行。

  2. 四大组件?

    Android四大组件是指Activity、Service、Broadcast Receiver和Content Provider。它们是Android应用程序开发的基本构建块,用于实现不同的应用程序功能。

    1. Activity:Activity是Android应用程序中用户界面的基本组件。每个Activity都代表一个屏幕,用户可以在不同的Activity之间进行切换。
    2. Service:Service是在后台运行的组件,它可以执行长时间运行的操作,例如网络操作或音乐播放。Service没有用户界面,但它可以与Activity进行通信。
    3. Broadcast Receiver:Broadcast Receiver是一种用于接收系统广播的组件。它可以接收来自系统或其他应用程序的广播消息,并执行相应的操作。
    4. Content Provider:Content Provider是一种用于管理应用程序数据的组件。它可以提供应用程序数据的访问和共享,例如联系人数据或照片库。

    这些四大组件可以结合使用,以实现不同类型的应用程序功能。例如,您可以在Activity中启动Service来执行后台操作,或使用Content Provider来共享数据。

  3. Activity 生命周期?

    Activity生命周期是指Activity从创建到销毁的整个过程,其中包括以下几个阶段:

    1. onCreate():当Activity第一次创建时调用,用于执行一些初始化操作,例如设置布局和变量。
    2. onStart():当Activity已经可见但还无法与用户进行交互时调用,例如Activity被另一个Activity部分遮挡时。
    3. onResume():当Activity已经可见并且可以与用户进行交互时调用,例如Activity从后台返回前台时。
    4. onPause():当Activity失去焦点但仍然可见时调用,例如另一个Activity部分遮挡了当前Activity。
    5. onStop():当Activity不再可见时调用,例如用户打开了另一个应用程序或返回到主屏幕。
    6. onRestart():当Activity从停止状态重新开始时调用,例如用户返回到应用程序后。
    7. onDestroy():当Activity被销毁时调用,例如用户按下返回按钮或系统内存不足时。

    在Activity生命周期中,开发人员可以根据需要执行一些操作,例如保存和恢复状态、释放资源等。

  4. Intent: 理解显示与隐式的区别、隐式 Intent-filter 三部分?

    Intent是Android系统中的一种消息传递机制,用于在不同组件之间传递数据或启动组件。

    Intent分为显示Intent和隐式Intent两种类型:

    1. 显示Intent:指明了要启动的组件的类名,例如启动一个Activity。

    2. 隐式Intent:没有指明要启动的组件的类名,而是指定了一些操作和数据,让系统去查找合适的组件来处理。

    隐式Intent包括三个主要部分:

    1. Action:指定了要执行的操作,例如ACTION_VIEW表示查看数据。

    2. Category:指定了Intent所属的类别,例如CATEGORY_DEFAULT表示默认类别。

    3. Data:指定了Intent要处理的数据,例如URI和MIME类型。

    通过这三个部分,隐式Intent可以让系统查找合适的组件来处理特定的操作和数据,从而实现组件之间的通信。

  5. Android Activity 四种启动模式?

    Android Activity有四种启动模式,分别是:

    1. standard:标准模式,每次启动Activity都会创建一个新的实例,并放入任务栈中。
    2. singleTop:栈顶复用模式,如果要启动的Activity已经位于任务栈的栈顶,则不会创建新的实例,而是直接使用位于栈顶的实例。
    3. singleTask:单例模式,如果要启动的Activity已经存在于任务栈中,则会直接调用该Activity的onNewIntent()方法,同时将该Activity以上的所有Activity弹出栈。
    4. singleInstance:单独实例模式,该模式下的Activity只能存在于任务栈中的一个实例,系统会为其创建一个新的任务栈,并且该任务栈只包含该Activity。

    不同的启动模式可以为应用程序提供不同的功能和体验,但需要注意合理使用,以避免出现意外情况。

  6. Android 布局方式,控件居中?

    Android中常用的布局方式有LinearLayout、RelativeLayout、FrameLayout、ConstraintLayout等。

    要实现控件居中,可以使用以下两种方式:

    1. 在布局中使用gravity属性,例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!" />

    </LinearLayout>

    这样可以使TextView在LinearLayout中居中。

    1. 在布局中使用layout_gravity属性,例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:layout_gravity="center" />

    </FrameLayout>

    这样可以使TextView在FrameLayout中居中。

  7. Fragment:生命周期?

    Fragment生命周期包括以下几个阶段:

    1. onAttach():当Fragment与Activity关联时调用,可以通过该方法获取到对应的Activity实例。

    2. onCreate():当Fragment第一次创建时调用,用于执行一些初始化操作,例如设置变量和加载布局。

    3. onCreateView():当Fragment要显示UI时调用,用于加载布局和初始化UI控件。

    4. onActivityCreated():当Fragment所属的Activity完成onCreate()方法时调用,表示Activity和Fragment的View已经创建完成。

    5. onStart():当Fragment可见但还无法与用户进行交互时调用,例如Fragment被另一个Fragment部分遮挡时。

    6. onResume():当Fragment已经可见并且可以与用户进行交互时调用,例如Fragment从后台返回前台时。

    7. onPause():当Fragment失去焦点但仍然可见时调用,例如另一个Fragment部分遮挡了当前Fragment。

    8. onStop():当Fragment不再可见时调用,例如用户打开了另一个应用程序或返回到主屏幕。

    9. onDestroyView():当Fragment的UI被销毁时调用。

    10. onDestroy():当Fragment被销毁时调用。

    11. onDetach():当Fragment与Activity解除关联时调用。

  8. Activity 中的常用方法: setContentView,R.layout.XXX?

    Activity中的常用方法包括:

    1. setContentView():用于设置Activity的布局文件,例如:
    1
    setContentView(R.layout.activity_main);

    这样就可以将activity_main.xml布局文件设置为当前Activity的界面。

    1. findViewById():用于获取布局文件中的控件实例,例如:
    1
    TextView textView = findViewById(R.id.text_view);

    这样就可以获取布局文件中id为text_view的TextView控件实例。

    1. startActivity():用于启动另一个Activity,例如:
    1
    2
    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
    startActivity(intent);

    这样就可以启动SecondActivity。

    1. startActivityForResult():用于启动另一个Activity,并获取返回的结果,例如:
    1
    2
    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
    startActivityForResult(intent, REQUEST_CODE);

    这样就可以启动SecondActivity,并在该Activity返回结果时接收到回调。

    1. onBackPressed():用于处理返回键事件,例如:
    1
    2
    3
    4
    @Override
    public void onBackPressed() {
    // 处理返回键事件
    }

    这样就可以在用户按下返回键时执行相应的操作。

  9. Android 尺寸单位 px,dp,sp,资源ID:新加 id 和引用已经存在的id?

    在Android中,有几种常用的尺寸单位:px(像素)、dp(设备独立像素)、sp(缩放独立像素)。

    1. px(像素):最基本的尺寸单位,它表示屏幕上的一个像素点。px单位是绝对单位,不会根据屏幕的密度进行缩放。在编写布局文件时,可以使用px作为宽度、高度等属性的单位。
    2. dp(设备独立像素):dp是一种相对单位,它会根据屏幕的密度进行缩放,以适应不同密度的屏幕。在编写布局文件时,推荐使用dp作为宽度、高度等属性的单位,以确保布局在不同设备上的一致性。
    3. sp(缩放独立像素):sp也是一种相对单位,它会根据用户的字体大小偏好进行缩放。通常用于文本大小的设置,以确保文本在不同设备上的可读性。

    在Android中,还有一个重要的概念是资源ID。资源ID是一个唯一标识符,用于引用Android应用程序中的各种资源,如布局文件、字符串、图像等。每个资源都有一个独特的资源ID,可以通过在代码中使用R类来引用这些资源。

    如果要新加一个资源ID,可以在res目录下的相应文件夹中添加对应的资源文件,然后在代码中使用R类引用该资源ID。如果要引用已经存在的资源ID,可以直接在代码中使用R类引用该资源ID。

  10. 常用控件如 webview、checkbox 的属性 isChecked、Snackbar?

    常用控件如 WebView、CheckBox具有一些常用的属性和方法,下面是其中几个常见的属性和方法:

    1. WebView:
    • loadUrl(String url):加载指定的URL网页。
    • loadData(String data, String mimeType, String encoding):加载指定的数据,可以是HTML字符串或者本地文件的内容。
    • setWebViewClient(WebViewClient client):设置WebView的客户端,用于处理页面加载事件。
    • setWebChromeClient(WebChromeClient client):设置WebView的Chrome客户端,用于处理页面加载进度、JavaScript对话框等事件。
    1. CheckBox:
    • isChecked():返回CheckBox的选中状态,返回值为boolean类型。
    • setChecked(boolean checked):设置CheckBox的选中状态。
    • setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener):设置CheckBox的选中状态改变监听器,用于监听CheckBox的选中状态改变事件。
    1. Snackbar:
    • make(View view, CharSequence text, int duration):创建一个Snackbar实例。
    • setText(CharSequence text):设置Snackbar的文本内容。
    • setAction(CharSequence text, View.OnClickListener listener):设置Snackbar的操作按钮及其点击事件。
    • setDuration(int duration):设置Snackbar显示的持续时间。
    • show():显示Snackbar。

    这些属性和方法可以根据具体的需求来使用,以实现相应的功能。

  11. Android Log 日志级别: Verbose (Log.v) 、Debug(Log.d)、Info(Log.i)、Warning(Log.w)、Error(Log.e)?

    在Android中,有几个常用的日志级别,可以用于在代码中输出日志信息,方便调试和查看程序运行时的状态。以下是常用的日志级别及其对应的方法:

    1. Verbose (Log.v):用于输出详细的日志信息,通常用于调试和追踪代码的执行流程。

      • Log.v(String tag, String msg):输出Verbose级别的日志信息。
    2. Debug (Log.d):用于输出调试信息,通常用于在开发阶段调试程序。

      • Log.d(String tag, String msg):输出Debug级别的日志信息。
    3. Info (Log.i):用于输出一般的信息性日志,例如程序的运行状态、操作结果等。

      • Log.i(String tag, String msg):输出Info级别的日志信息。
    4. Warning (Log.w):用于输出警告信息,表示程序可能出现潜在的问题,但不会导致程序崩溃。

      • Log.w(String tag, String msg):输出Warning级别的日志信息。
    5. Error (Log.e):用于输出错误信息,表示程序发生了错误或异常。

      • Log.e(String tag, String msg):输出Error级别的日志信息。

    这些日志级别可以根据需要选择合适的级别,在代码中使用对应的方法输出日志信息。在发布正式版本时,建议将日志级别设置为适当的级别,避免不必要的日志输出。

  12. Android Home 键或者返回键对 Activity 的影响?

    Android的Home键和返回键对Activity有不同的影响:

    1. Home键:按下Home键会使当前Activity进入后台,返回到桌面。此时,当前Activity会触发onPause()、onStop()和onSaveInstanceState()等生命周期方法。当用户再次打开应用程序时,会重新调用onRestart()、onStart()和onResume()等生命周期方法来恢复Activity的状态。
    2. 返回键:按下返回键会销毁当前Activity,并返回到上一个Activity。此时,当前Activity会触发onPause()和onStop()等生命周期方法,然后被销毁,最后上一个Activity会调用onRestart()、onStart()和onResume()等生命周期方法来恢复。

    需要注意的是,返回键的行为可以通过重写Activity的onBackPressed()方法来自定义。可以在该方法中实现自定义的返回逻辑,例如弹出对话框确认是否退出应用程序。

    另外,需要注意的是,当Activity进入后台或被销毁时,系统可能会回收其资源以释放内存。因此,开发者需要在适当的生命周期方法中保存和恢复Activity的状态,以确保用户体验的连续性。

  13. MediaPlayer 的用法?

    MediaPlayer是Android提供的用于播放音频和视频的类。以下是使用MediaPlayer的基本步骤:

    1. 创建MediaPlayer对象:

      1
      MediaPlayer mediaPlayer = new MediaPlayer();
    2. 设置数据源:

      • 从本地文件中设置数据源:
        1
        mediaPlayer.setDataSource(filePath);
      • 从网络URL中设置数据源:
        1
        mediaPlayer.setDataSource(url);
      • 从资源文件中设置数据源:
        1
        mediaPlayer.setDataSource(context, resId);
    3. 准备MediaPlayer:

      1
      mediaPlayer.prepare();
    4. 设置监听器(可选):

      1
      2
      3
      mediaPlayer.setOnPreparedListener(listener); // 准备完成监听器
      mediaPlayer.setOnCompletionListener(listener); // 播放完成监听器
      mediaPlayer.setOnErrorListener(listener); // 错误监听器
    5. 开始播放:

      1
      mediaPlayer.start();
    6. 暂停播放:

      1
      mediaPlayer.pause();
    7. 停止播放:

      1
      mediaPlayer.stop();
    8. 释放资源:

      1
      mediaPlayer.release();

    需要注意的是,MediaPlayer的操作涉及到IO操作和耗时操作,建议在子线程中执行,以避免阻塞主线程。另外,还可以使用MediaPlayer的其他方法来控制音频的音量、进度等。详细的用法可以参考Android官方文档。

  14. 菜单分类: 0ptionsMenu、 ContextMenu,PopupMenu?

    在Android中,有三种常见的菜单分类:OptionsMenu、ContextMenu和PopupMenu。

    1. OptionsMenu(选项菜单): OptionsMenu是位于Activity的顶部工具栏(ActionBar)上的菜单,通常包含应用程序的常用操作。OptionsMenu可以通过重写Activity的onCreateOptionsMenu()方法来创建,并通过调用invalidateOptionsMenu()方法来更新菜单项。用户可以通过按下设备的菜单键(Menu键)或者在工具栏上点击菜单按钮来显示OptionsMenu。
    2. ContextMenu(上下文菜单): ContextMenu是在View上长按时弹出的菜单,通常包含与该View相关的操作。ContextMenu可以通过重写View的onCreateContextMenu()方法来创建,并通过调用registerForContextMenu()方法将View注册为上下文菜单的触发器。用户长按View时,会弹出ContextMenu供用户选择操作。
    3. PopupMenu(弹出菜单): PopupMenu是一个弹出式的菜单,可以在任意位置显示。PopupMenu可以通过创建PopupMenu对象,并通过调用PopupMenu的inflate()方法来创建菜单项。然后,可以使用show()方法将PopupMenu显示在指定的位置上。PopupMenu通常用于在特定的触发事件(例如按钮点击)后显示菜单。

    这三种菜单分类在功能和使用场景上有所区别,开发者可以根据需求选择合适的菜单类型来实现相应的功能。

  15. Service 启动方式,生命周期,之间的区别?

    在Android中,Service是一种在后台执行长时间运行操作的组件。Service可以通过两种方式启动:启动式启动(Started)和绑定式启动(Bound)。

    1. 启动式启动(Started):

      • 启动Service:通过调用Context的startService()方法来启动Service。启动Service后,Service会在后台独立运行,即使启动Service的组件(如Activity)被销毁,Service仍会继续运行。
      • 停止Service:通过调用Context的stopService()方法或Service内部调用自身的stopSelf()方法来停止Service。停止Service后,Service会被销毁并停止运行。
    2. 绑定式启动(Bound):

      • 绑定Service:通过调用Context的bindService()方法来绑定Service。绑定Service后,组件(如Activity)可以与Service进行交互,通过IBinder对象获取Service的实例。
      • 解绑Service:通过调用Context的unbindService()方法来解绑Service。解绑Service后,Service会根据是否还有其他组件绑定而决定是否销毁。

    Service的生命周期包括以下几个方法:

    • onCreate():在Service创建时调用,用于进行一次性的初始化操作。
    • onStartCommand():在Service启动时调用,用于处理启动Service的请求。
    • onBind():在Service绑定时调用,用于返回一个IBinder对象,供组件与Service进行交互。
    • onUnbind():在Service解绑时调用,用于清理绑定相关的资源。
    • onDestroy():在Service销毁时调用,用于释放资源和进行清理操作。

    启动式启动和绑定式启动的区别如下:

    • 启动方式:启动式启动通过startService()方法启动,绑定式启动通过bindService()方法启动。
    • 生命周期:启动式启动的Service会一直运行,直到调用stopService()或stopSelf()方法停止;绑定式启动的Service会在所有绑定的组件解绑后销毁。
    • 交互性:启动式启动的Service不能直接与组件进行交互,只能通过Intent传递数据;绑定式启动的Service可以通过IBinder对象与组件进行交互。
    • 生命周期管理:启动式启动的Service不依赖于启动它的组件的生命周期,可以独立运行;绑定式启动的Service依赖于绑定它的组件的生命周期,当绑定的组件销毁时,Service也会被销毁。

    根据实际需求,开发者可以选择适合的启动方式来实现不同的功能。

  16. Android 数据存储方式: 文件存储 FileInputStream(append)、getSharedPreferences ,MODE PRIVATE、sqlite?

    在Android中,有多种方式可以进行数据存储,包括文件存储、SharedPreferences和SQLite数据库。

    1. 文件存储(File Storage):
      • 使用FileInputStream和FileOutputStream类可以进行文件的读写操作。可以使用FileInputStream来读取文件内容,使用FileOutputStream来写入文件内容。
      • 若要在现有文件的末尾追加内容,可以使用FileOutputStream的构造函数中的第二个参数来指定为true,表示追加模式。
      • 文件存储适用于存储较小的数据量,如配置文件、日志文件等。
    2. SharedPreferences:
      • SharedPreferences是Android提供的一种轻量级的存储方式,用于存储简单的键值对数据。
      • 使用getSharedPreferences()方法获取SharedPreferences对象,可以指定一个名称和一个访问模式(如MODE_PRIVATE)。
      • 使用SharedPreferences对象的edit()方法获取一个Editor对象,通过Editor对象的putXxx()方法存储数据,如putString()、putInt()等。
      • 使用Editor对象的commit()方法或apply()方法提交数据的修改。
    3. SQLite数据库:
      • SQLite是一种轻量级的关系型数据库,适用于存储结构化数据。
      • 使用SQLiteOpenHelper类来创建和管理数据库。可以继承SQLiteOpenHelper类,并重写onCreate()和onUpgrade()方法。
      • 使用SQLiteDatabase类进行数据库的增删改查操作。可以使用execSQL()方法执行SQL语句,或使用insert()、update()、delete()、query()等方法进行数据操作。

    这些存储方式各有特点,适用于不同的数据存储需求。文件存储适用于存储简单的文本数据或二进制数据;SharedPreferences适用于存储简单的键值对数据;SQLite数据库适用于存储结构化数据或大量的数据。开发者可以根据具体的需求选择合适的存储方式。

  17. SqliteOpenHelper,SqliteDatabase 的用法?

    SQLiteOpenHelper和SQLiteDatabase是Android中用于操作SQLite数据库的两个重要类。

    1. SQLiteOpenHelper:

      • SQLiteOpenHelper是一个抽象类,用于创建和管理SQLite数据库。
      • 需要继承SQLiteOpenHelper类,并重写onCreate()和onUpgrade()方法。
      • onCreate()方法在数据库第一次创建时调用,用于创建数据库表和初始化数据。
      • onUpgrade()方法在数据库版本更新时调用,用于更新数据库结构或数据迁移。
      • 在子类中,可以通过调用getWritableDatabase()或getReadableDatabase()方法来获取一个可读写或只读的SQLiteDatabase对象。
    2. SQLiteDatabase:

      • SQLiteDatabase是用于执行SQL语句和操作数据库的类。
      • 可以使用execSQL()方法执行SQL语句,如创建表、插入数据、更新数据、删除数据等。
      • 可以使用insert()方法插入数据,update()方法更新数据,delete()方法删除数据。
      • 可以使用query()方法查询数据,通过传入表名、列名、条件等参数来进行查询。查询结果以Cursor对象返回。
      • 可以使用beginTransaction()、setTransactionSuccessful()和endTransaction()方法进行事务管理,保证数据的一致性和完整性。

    使用SQLiteOpenHelper和SQLiteDatabase可以方便地进行数据库的创建、升级和操作。在创建SQLiteOpenHelper的子类时,需要指定数据库的名称、版本号和其他相关参数。在操作数据库时,可以使用SQLiteDatabase的方法来执行SQL语句和操作数据。开发者可以根据具体的需求,使用相应的方法来实现对数据库的操作。

  18. Android 广播: 静态和动态注册,有序和无序(优先级)?

    在Android中,广播是一种用于应用程序之间或应用程序内部进行通信的机制。广播可以分为静态注册和动态注册,以及有序广播和无序广播。

    1. 静态注册(Static Registration):
      • 静态注册是在AndroidManifest.xml文件中声明广播接收器(BroadcastReceiver)的方式。
      • 静态注册的广播接收器在应用程序安装时就会被注册,并且可以在应用程序未运行的情况下接收广播。
      • 静态注册的广播接收器可以接收系统级别的广播,如网络状态变化、电池电量变化等。
      • 静态注册的广播接收器在应用程序被卸载时会被自动取消注册。
    2. 动态注册(Dynamic Registration):
      • 动态注册是在代码中通过调用registerReceiver()方法注册广播接收器的方式。
      • 动态注册的广播接收器在应用程序运行时注册,并且只能在应用程序运行期间接收广播。
      • 动态注册的广播接收器可以接收应用程序级别的广播,如自定义的广播等。
      • 动态注册的广播接收器需要在不需要接收广播时调用unregisterReceiver()方法进行取消注册。
    3. 有序广播(Ordered Broadcast):
      • 有序广播是一种按照优先级顺序依次传递给广播接收器的广播。
      • 广播接收器可以通过设置优先级来指定自己的接收顺序,优先级越高的接收器会先收到广播。
      • 在接收器中可以通过调用abortBroadcast()方法来中断广播的传递,后续的接收器将无法收到该广播。
    4. 无序广播(Normal Broadcast):
      • 无序广播是一种同时传递给所有广播接收器的广播,没有固定的接收顺序。
      • 广播接收器无法控制接收广播的顺序,也无法中断广播的传递。

    开发者可以根据实际需求选择静态注册或动态注册的方式来接收广播,并可以根据需要选择有序广播或无序广播。有序广播适用于需要按照优先级顺序处理广播的场景,而无序广播适用于同时通知多个接收器的场景。

  19. HttpUrlConnection 用法,配置读取和写入的 timeout?

    HttpUrlConnection是Android中用于进行HTTP通信的类。下面是HttpUrlConnection的基本用法以及如何配置读取和写入的timeout。

    1. 创建HttpUrlConnection对象:

      1
      2
      URL url = new URL("http://www.example.com");
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    2. 设置请求方法和其他属性:

      1
      2
      3
      4
      5
      connection.setRequestMethod("GET"); // 设置请求方法,如GET、POST等
      connection.setConnectTimeout(5000); // 设置连接超时时间,单位为毫秒
      connection.setReadTimeout(5000); // 设置读取超时时间,单位为毫秒
      connection.setDoInput(true); // 设置是否允许输入流,默认为true
      connection.setDoOutput(true); // 设置是否允许输出流,默认为false
    3. 发起HTTP请求:

      1
      2
      connection.connect(); // 连接服务器
      int responseCode = connection.getResponseCode(); // 获取服务器响应码
    4. 读取服务器响应:

      1
      2
      3
      4
      5
      6
      7
      8
      InputStream inputStream = connection.getInputStream(); // 获取输入流
      BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
      StringBuilder response = new StringBuilder();
      String line;
      while ((line = reader.readLine()) != null) {
      response.append(line);
      }
      reader.close();
    5. 关闭连接:

      1
      connection.disconnect();

    配置读取和写入的timeout:

    • setConnectTimeout(int timeout):设置连接超时时间,即连接服务器的时间。如果在指定的时间内未能建立连接,将会抛出SocketTimeoutException。
    • setReadTimeout(int timeout):设置读取超时时间,即从服务器读取数据的时间。如果在指定的时间内未能读取完数据,将会抛出SocketTimeoutException。

    例如,以下代码将连接超时时间设置为5秒,读取超时时间设置为10秒:

    1
    2
    connection.setConnectTimeout(5000);
    connection.setReadTimeout(10000);

    通过合理设置连接超时和读取超时时间,可以提高网络请求的稳定性和响应速度。

  20. 权限配置AndroidManifest.xml 中的、标签内容属性?

    在AndroidManifest.xml文件中使用标签来配置应用程序所需的权限。这些权限用于控制应用程序对设备功能和资源的访问权限。以下是标签的常见属性:

    1. android:name:指定权限的名称,例如android.permission.CAMERA表示相机权限。
    2. android:maxSdkVersion:指定权限的最大SDK版本。可以使用这个属性来限制权限在特定版本的Android上可用。
    3. android:minSdkVersion:指定权限的最小SDK版本。可以使用这个属性来限制权限仅在特定版本的Android上可用。
    4. android:required:指定权限是否是必需的。如果设置为true,表示应用程序必须拥有此权限才能安装和运行。如果设置为false,表示应用程序可以运行,但可能无法访问相关功能。
    5. android:protectionLevel:指定权限的保护级别。常见的保护级别包括:
      • normal:普通权限,不涉及敏感信息或危险操作。
      • dangerous:危险权限,可能涉及用户隐私或对设备功能的敏感操作,如读取联系人、发送短信等。
      • signature:只有在应用程序与请求权限的应用程序具有相同的签名时,才能获得此权限。
      • signatureOrSystem:只有在应用程序与请求权限的应用程序具有相同的签名,或者是系统应用程序时,才能获得此权限。

    示例:

    注意:在AndroidManifest.xml中配置权限时,需要确保权限的使用是合理和必要的,以保护用户的隐私和设备的安全。不要滥用权限,只请求应用程序所需的权限。

  21. Json:如何表达数组?

    在Android中,使用JSON表示数组的方式与标准JSON格式一致。可以使用JSONArray类来创建和操作JSON数组。以下是几种在Android中表示数组的方式:

    1. 字符串数组:

      1
      2
      3
      4
      JSONArray jsonArray = new JSONArray();
      jsonArray.put("apple");
      jsonArray.put("banana");
      jsonArray.put("orange");
    2. 数字数组:

      1
      2
      3
      4
      JSONArray jsonArray = new JSONArray();
      jsonArray.put(1);
      jsonArray.put(2);
      jsonArray.put(3);
    3. 布尔值数组:

      1
      2
      3
      4
      JSONArray jsonArray = new JSONArray();
      jsonArray.put(true);
      jsonArray.put(false);
      jsonArray.put(true);
    4. 对象数组:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      JSONArray jsonArray = new JSONArray();
      JSONObject jsonObject1 = new JSONObject();
      jsonObject1.put("name", "John");
      jsonObject1.put("age", 25);
      jsonArray.put(jsonObject1);

      JSONObject jsonObject2 = new JSONObject();
      jsonObject2.put("name", "Jane");
      jsonObject2.put("age", 30);
      jsonArray.put(jsonObject2);

      JSONObject jsonObject3 = new JSONObject();
      jsonObject3.put("name", "Tom");
      jsonObject3.put("age", 35);
      jsonArray.put(jsonObject3);
    5. 嵌套数组:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      JSONArray jsonArray = new JSONArray();
      JSONArray innerArray1 = new JSONArray();
      innerArray1.put(1);
      innerArray1.put(2);
      innerArray1.put(3);
      jsonArray.put(innerArray1);

      JSONArray innerArray2 = new JSONArray();
      innerArray2.put(4);
      innerArray2.put(5);
      innerArray2.put(6);
      jsonArray.put(innerArray2);

      JSONArray innerArray3 = new JSONArray();
      innerArray3.put(7);
      innerArray3.put(8);
      innerArray3.put(9);
      jsonArray.put(innerArray3);

    在Android中,可以使用JSONArray的get()方法和length()方法来访问和遍历数组中的元素。例如,对于上述的字符串数组,可以使用以下代码来访问其中的元素:

    1
    2
    3
    4
    String firstElement = jsonArray.getString(0); // "apple"
    String secondElement = jsonArray.getString(1); // "banana"
    String thirdElement = jsonArray.getString(2); // "orange"
    int arrayLength = jsonArray.length(); // 3

    注意:在Android中,使用JSON表示数组时,需要确保数组的元素类型正确,并使用相应的方法来获取和操作数组中的元素。

  22. 列表控件 ListView,RecyclerView,Adapter 用法?

    ListView、RecyclerView和Adapter是Android中常用的列表控件和适配器。它们的用法如下:

    1. ListView:

      • 在布局文件中添加ListView控件:

        1
        2
        3
        4
        <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
      • 在代码中获取ListView控件的引用:

        1
        ListView listView = findViewById(R.id.list_view);
      • 创建一个适配器(Adapter)并设置给ListView:

        1
        2
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
        listView.setAdapter(adapter);
      • 设置ListView的点击事件监听器:

        1
        2
        3
        4
        5
        6
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // 处理点击事件
        }
        });
    2. RecyclerView:

      • 在布局文件中添加RecyclerView控件:

        1
        2
        3
        4
        <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
      • 在代码中获取RecyclerView控件的引用:

        1
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
      • 创建一个布局管理器(LayoutManager)并设置给RecyclerView:

        1
        2
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
      • 创建一个适配器(Adapter)并设置给RecyclerView:

        1
        2
        MyAdapter adapter = new MyAdapter(data);
        recyclerView.setAdapter(adapter);
      • 创建一个自定义的ViewHolder类,继承自RecyclerView.ViewHolder,并在适配器中实现ViewHolder的创建和数据绑定逻辑。

      • 设置RecyclerView的点击事件监听器:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        // 处理点击事件
        return false;
        }

        @Override
        public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        }
        });
    3. Adapter:

      • 创建一个继承自BaseAdapter或RecyclerView.Adapter的适配器类,并实现必要的方法,如getItemCount()、getView()(对于BaseAdapter)或onCreateViewHolder()、onBindViewHolder()(对于RecyclerView.Adapter)。
      • 在适配器中定义数据集合,并提供方法用于更新数据。
      • 在getView()或onBindViewHolder()方法中,根据位置获取数据,并将数据绑定到列表项的视图上。
      • 在需要更新数据时,调用适配器的相应方法(如notifyDataSetChanged())来刷新列表。

    通过ListView、RecyclerView和Adapter的组合使用,可以实现灵活和高效的列表展示和交互功能。具体的用法可以根据实际需求进行调整和扩展。

  23. Handler、Message、Looper 机制,消息发送和接收处理的方法?

    在Android中,Handler、Message和Looper是用于实现线程间通信的机制。它们的工作原理如下:

    1. Handler:

      • Handler是Android中的一个类,用于发送和处理消息。
      • 在主线程中创建一个Handler对象,可以将其与主线程的Looper关联起来,从而使得Handler可以接收并处理消息。
      • Handler可以通过sendMessage()方法发送消息,也可以通过post()方法发送Runnable对象。
      • Handler还可以通过postDelayed()方法发送延时消息。
    2. Message:

      • Message是Handler中的一个内部类,用于封装消息的内容。
      • 每个Message对象都有一个what字段和一个obj字段,可以分别用于传递消息的标识和数据。
      • 可以通过obtainMessage()方法获取一个Message对象,并设置其what和obj字段的值。
    3. Looper:

      • Looper是Android中的一个类,用于创建一个消息循环。
      • 在主线程中,Android会自动创建一个Looper对象,并将其与主线程绑定。
      • Looper通过调用loop()方法来启动消息循环,该方法会不断地从消息队列中取出消息,并将其分发给Handler进行处理。

    消息发送和接收处理的方法如下:

    1. 发送消息:

      • 使用Handler的sendMessage()方法发送消息,可以创建一个Message对象并设置其what和obj字段的值,然后调用sendMessage()方法发送消息。
      • 使用Handler的post()方法发送Runnable对象,可以直接将Runnable对象作为参数传递给post()方法。
    2. 接收和处理消息:

      • 在主线程中创建一个Handler对象,并重写其handleMessage()方法来处理消息。
      • 在handleMessage()方法中,根据接收到的消息的what字段来判断消息的类型,并根据需要进行相应的处理操作。

    以下是一个示例代码,演示了如何使用Handler、Message和Looper来发送和接收消息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    // 在主线程中创建一个Handler对象
    Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    switch (msg.what) {
    case 1:
    // 处理消息类型为1的消息
    String data = (String) msg.obj;
    // 执行相应的操作
    break;
    case 2:
    // 处理消息类型为2的消息
    // 执行相应的操作
    break;
    // 其他消息类型的处理...
    }
    }
    };

    // 在子线程中发送消息
    new Thread(new Runnable() {
    @Override
    public void run() {
    // 创建一个Message对象,并设置其what和obj字段的值
    Message message = Message.obtain();
    message.what = 1;
    message.obj = "Hello";
    // 发送消息
    handler.sendMessage(message);
    }
    }).start();

    通过Handler、Message和Looper机制,可以实现线程间的消息传递和处理,从而实现线程间的通信和协作。在实际开发中,可以根据具体的需求和场景,灵活地使用这些机制来实现各种功能。

  24. AsyncTask 内部实现的方法?

    AsyncTask是Android中用于在后台线程执行异步任务并在主线程更新UI的一个便捷类。它封装了线程的创建和管理,使得开发者可以更方便地进行异步操作。AsyncTask类内部实现了以下几个方法:

    1. onPreExecute():

      • 在执行异步任务之前调用。
      • 运行在主线程中,可以在这里进行一些准备工作,如显示进度条等。
    2. doInBackground(Params…):

      • 在后台线程中执行耗时操作的方法。
      • 运行在后台线程中,不能在这里进行UI操作。
      • 在这个方法中可以通过调用publishProgress(Progress…)方法来发布进度信息。
    3. onProgressUpdate(Progress…):

      • 在调用publishProgress(Progress…)方法后,在主线程中执行的方法。
      • 运行在主线程中,可以在这里更新UI,如更新进度条的进度。
    4. onPostExecute(Result):

      • 在后台任务执行完毕后调用。
      • 运行在主线程中,可以在这里进行一些收尾工作,如隐藏进度条等。
      • doInBackground()方法的返回值会作为参数传递给这个方法。
    5. onCancelled():

      • 在任务被取消时调用。
      • 运行在主线程中,可以在这里进行一些清理工作。

    AsyncTask的使用方法如下:

    1. 创建一个继承自AsyncTask的子类,并指定三个泛型参数:Params、Progress和Result,分别表示输入参数、进度信息和返回结果的类型。

    2. 在子类中实现doInBackground()方法,用于执行后台任务。

    3. 在doInBackground()方法中,通过调用publishProgress(Progress…)方法来发布进度信息。

    4. 在子类中实现onProgressUpdate()方法,用于在主线程中更新UI。

    5. 在子类中实现onPostExecute()方法,用于在主线程中处理任务执行结果。

    6. 在需要执行异步任务的地方,创建子类的实例,并调用execute(Params…)方法来启动任务。

    以下是一个示例代码,演示了如何使用AsyncTask来执行异步任务并更新UI:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    private class MyTask extends AsyncTask<Void, Integer, String> {
    // 在后台线程中执行耗时操作
    @Override
    protected String doInBackground(Void... params) {
    for (int i = 0; i < 100; i++) {
    // 模拟耗时操作
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    // 发布进度信息
    publishProgress(i);
    }
    // 返回结果
    return "Task finished";
    }

    // 在主线程中更新进度条
    @Override
    protected void onProgressUpdate(Integer... values) {
    int progress = values[0];
    // 更新进度条的进度
    progressBar.setProgress(progress);
    }

    // 在主线程中处理任务执行结果
    @Override
    protected void onPostExecute(String result) {
    // 显示任务执行结果
    textView.setText(result);
    }
    }

    // 创建任务实例并启动任务
    MyTask task = new MyTask();
    task.execute();

    通过AsyncTask类的内部实现,我们可以方便地在后台线程执行耗时操作,并在主线程中更新UI,从而实现异步任务的执行和UI的更新。它简化了线程的管理和通信,使得开发者可以更专注于业务逻辑的实现。

  25. HarmonyOS Ability: FA、PA?

    Ability概述

    官方:Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个Ability),HarmonyOS支持应用以Ability为单位进行部署。Ability可以分为FA(Feature Ability)和PA(Particle Ability)两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。

    仅个人理解:Ability可以分为FA(Feature Ability)和PA(Particle Ability)两种类型

    1.FA(Feature Ability)可以比作你打开一个应用里面的各种页面,然后这些页面,组成了一个应用这里的FA其实可以约等于为Page Ability约等于page,因为我们在建立FA的时候,他会自动关联Slice,然后多余的AbilitySlice可以通过addActionRoute()方法来添加。

    2.PA(Particle Ability)其中PA支持Service Ability和Data Ability,然后这两个我基于官方文档所理解的是它们都是为前面FA所服务的,为FA提供数据支持,后台运行的能力

拓展

  1. 定义数组Array[]

  2. 定义无返回值函数 — unit

  3. 非空类的基类是—Any —避免空指针类型

  4. 所有类的子类 Nothing

  5. == 判断内容 === 判断对象的地址

  6. 定义类class 类默认为不可继承的 加open关键字后才能被继承

  7. 次级构造函数 直接写constructor 些public是可以被省略,如果写的事private 就不可被省略

  8. 定义属性定义在类声明的地方、例如:(var name :String = “”)去掉var就还是传递的一个参数

  9. field 幕后字段 考点 每一个属性都会定义到一个幕后字段,不复写就不定义幕后字段

  10. 方法前面不加open关键字那么这个方法是不可以呗复写的,加上open就可以被复写

  11. 参数的默认值:override overlord

  12. 密封类:sealed 限制类无限制的扩大

  13. 嵌套类,内部类之间的关系 什么都没加的交嵌套类(静态)inner 表示的就是内部类

  14. 局部内部类指方法体中或语句块中的类

  15. 匿名内部类 object: 差不多是一种没有名字的类,还可以实现一些抽象的接口

  16. abstract 抽象类定义

  17. 定义函数首先要加上fun 可有可无的返回值

  18. 高阶函数 —-? 函数的定义时一个郎木达的形式定义

  19. 数据的容器 可分为可变和不可变的

  20. 在Kotlin中,object关键字有两种用法:

    1. 单例 可以使用object关键字创建一个单例对象,这个对象只会被创建一次,可以直接使用它的成员变量和成员方法。这种方式不需要使用class关键字来定义类,也不需要使用构造函数来创建对象。

    下面是一个单例对象的示例代码:

    1
    2
    3
    4
    5
    6
    kotlin复制object Singleton {
    var count = 0
    fun increment() {
    count++
    }
    }

    在这个示例中,我们使用object关键字创建了一个名为Singleton的单例对象,它有一个成员变量count和一个成员方法increment。

    1. 匿名内部类 在Kotlin中,可以使用object关键字创建一个匿名内部类,这个类可以继承某个类或实现某个接口,并且可以重写它们的方法。这种方式通常用于创建回调函数或事件处理程序。

    下面是一个匿名内部类的示例代码:

    1
    2
    3
    4
    5
    button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
    // 处理点击事件
    }
    })

    在这个示例中,我们使用object关键字创建了一个匿名内部类,并实现了View.OnClickListener接口的onClick方法,用于处理按钮的点击事件。

  21. 复写的重要性

    在Android开发中,重写(Override)是一种常见的技术手段,用于在子类中覆盖父类的方法或者接口的方法,以实现自定义的逻辑。重写的重要性体现在以下几个方面:

    1. 实现多态性:重写是实现多态性的关键机制之一。通过重写父类的方法,子类可以根据自身的需求来重新定义方法的行为。这样,在程序运行时,可以根据对象的实际类型来调用相应的方法,实现不同对象的不同行为。

    2. 扩展功能:通过重写,可以在子类中扩展父类的功能。子类可以在重写的方法中添加新的逻辑,或者修改父类方法的实现细节,从而实现更加灵活和丰富的功能。

    3. 实现回调机制:在Android开发中,常常使用回调机制来实现异步操作或者事件的处理。通过重写回调方法,可以在适当的时机执行自定义的逻辑,以响应异步操作或者事件的发生。

    4. 实现接口规范:在实现接口时,需要重写接口中定义的所有方法。通过重写这些方法,可以确保子类符合接口的规范,从而实现接口的完整性和一致性。

    5. 提高代码的可读性和可维护性:通过重写,可以将相关的逻辑集中在一处,使得代码更加清晰和易于理解。同时,当需要修改某个功能时,只需要修改重写的方法,而不需要修改其他地方的代码,从而提高了代码的可维护性。

    重写是面向对象编程中的重要概念,它允许子类根据自身的需求来重新定义父类的方法。通过合理地使用重写,可以实现更加灵活、可扩展和可维护的代码。