【Android笔记】Android常见知识

1,279 阅读18分钟

Snipaste_2023-06-15_17-35-28.png

一:View

一、 通用介绍

1、px dp dpi sp

  1. 关于 dp dip dpi ppi px sp 你应该知道的一切
  • px是物理像素点,dpi 对角线每英寸像素点,
  • dp,与px的像素比,Android规定在160dpi的设备上1dp=1px...以此类推。可以解决不同机型大小不一致的问题;
  • sp,一般给文字设置,用于文字随系统字体大小变化,不需要这个效果可以设置dp。
  • 分辨率讲的是px像素量比值,如1080p的分辨率是宽度108016/9=19201080,得到高度1920。只靠分辨率还不能确定dpi(像素密度),还受屏幕尺寸变量影响。
  • 去几x文件判断的是dpi最大值与上一个最大值的区间,320,480,640对应从小到大三类x右侧闭区间。
  1. 安卓默认的分辨率对应dpi: 听说你还在用dp做屏幕适配?
  • 所以会有x 720,xx 1080,xxx 2k的说法。
  1. 标准屏 iphone 6为界:375x667
  • 360x800也是蛮常见的

2、动态设置View的高度和宽度,ViewTreeObserver使用

3、 Android ViewTreeObserver 原理详解

4、获取View的位置

  1. Android:6种高效 & 准确获取View坐标位置的方式

5、descendantFocusability:控制父/子布局获得焦点 descendantFocusability属性的简介和用处

6、一些点击事件防穿透可以使用这个

android:clickable="true"
android:focusable="true"

7、子布局可越界:android:clipChildren="false"

  • 用法是这样的,只写一个就行了,写的位置和第一个父布局关系不大,关键在于想在那个模块里显示出来,在顶层的那个模块中写一个就行

8、TextView,字符相关常见知识

9、include

mBindView.includeAdd.root.showOrHide(list.isEmpty())

这个root还蛮关键的,对include,点击事件与可见都要用这个

10、raw和Asset轻读一下 Android 应用开发中的 assets 目录

二、 ImageView

1、src的执行时机在onbackgroud后: 彻底记住ImageView的background和src的区别

2、新的圆角图片方式(见Cons中)

3、 颜色透明度 16进制对应表_十六进制透明度

8、Android:screenOrientation属性

  1. Android:screenOrientation属性_可乐+冰0的博客-CSDN博客
  • unspecified,默认值,由系统决定,不同手机可能不一致
  • landscape,强制横屏显示
  • portrait,强制竖屏显示
  • sensor,根据物理传感器方向转动,用户90度、180度、270度旋转手机方向,activity都更着变化

9、格式

  1. android:scaleType="centerCrop"

以填满整个ImageView为目的,将原图的中心对准ImageView的中心,等比例放大原图,直到填满ImageView为止(指的是ImageView的宽和高都要填满),原图超过ImageView的部分作裁剪处理。

  1. android:scaleType="fitXY"

把原图按照指定的大小在View中显示,拉伸显示图片,不保持原比例,填满ImageView.

  1. fitCenter:   

把图片按比例扩大/缩小到View的宽度,居中显示

三、 ConstraintLayout

基本思想:某个控件的某处关于某个对象的某处对齐

1、基本模块:史上最全ConstraintLayout使用详解

  1. 百分比偏移:bias
  1. 链式,常用的packed:chainStyle
  • packed模式如果设置两个共同居中,若隐藏其中一个,另外一个会自动居中
  1. 参考线:Guideline
  2. 分组:Group与app:constraint_referenced_ids:
  3. 圆角图片:ImageFilterButton和ImageFilterView
  • roundPercent接受的值类型是0-1的小数
  • round=可以设置具体圆角的大小
  • altSrc来设置第二个图片资源
  • crossfade设置堆叠效果

2、 宽高比:Android中使控件保持固定宽高比的几种方式

  1. 父布局为Cons;
  • 样例:需要计算高,dp_0;宽比高为3:4;
  <androidx.appcompat.widget.AppCompatImageView
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintDimensionRatio="h,3:4"
            android:id="@+id/cover"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_0"
            android:background="@drawable/ic_cover_album"
            android:scaleType="centerCrop" />

3、 实现权重

  1. 使用属性:app:layout_constraintHorizontal_weight="x" (以宽为例)
  2. 确立view间上下(对应height=0dp)/左右(weight="0dp")联动关系即可。

4、 改变约束关系

  1. 代码中使用updateLayoutParams改变布局及相关参数:约束布局(ConstraintLayout)的一些技巧
  • 指定16:9视频宽拉伸,长度自适应:
 view.updateLayoutParams<ConstraintLayout.LayoutParams> { height = 0 dimensionRatio = "h,9:16" }
  1. ConstraintLayout动态添加View,改变约束
  • 代码中使用:ConstraintLayout.LayoutParams.UNSET 可以清除约束关系

5、 与其他View的联动

  • ConsttratLayou中用0dp拉升后,maxwidth就无效了
  1. ScrollView
android:layout_height="wrap_content"
android:paddingBottom="12dp"

6、 动态调整宽高:

  1. Android动态设置Margin的方法,xml与代码中add的不一样

  2. 样例写法一:

  val viewWidth = if (toastState == STORAGE_LESS) R.dimen.dp_349 else R.dimen.dp_343

        控件名.apply {
            val lp = layoutParams
            lp.width = resources.getDimensionPixelSize(viewWidth)
            lp.setMargins(0, 0, 0, 1800)
            layoutParams = lp
        }
  • padding是view内部的属性,可以直接调整;margin是layoutParams与外界关系的属性;
  1. 写法二:
 //方式二直接通过getLayoutParams获取属性修改
        button.getLayoutParams().width=250
        button.getLayoutParams().height = 250

7、常见设置

  • 左对齐不管是根据左边控件的左边还是右边,左边隐藏了,一律会变成ss这种;左边控件原本的padding不会继承(合理),margin也不会被右边控件继承(挺好的)

  • 虽然控件左边的为Gone,但本身左边的margin仍然保留,这个时候可以用 app:layout_goneMarginStart="xdp" 相对控件隐藏时控制间距

8、Flow 流式布局

  • app:flow_wrapMode="chain" 好东西,自动换行
  • 实现竖排很横排的方式没,在2.0.4版本加入

9、ConstraintLayout不支持-margin的替代方案

  • 使用 Guideline
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="50dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 使用对子view使用偏移属性translationY
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:translationY="-50dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

10、切正式环境后,显示Log

image.png

四、 ScrollView

1、 只能有一个子View

2、 除去ScrollVIew拉到尽头时再拉的阴影效果

五、 FloatingActionButton基本使用及踩坑记录

1、图标尺寸

1、floatingactionbutton src图标不居中解决_weixin_41650019的博客-CSDN博客

  • app:fabCustomSize=“50dp” 实测有效 2、app:maxImageSize 的属性即可直接设置图标大小了,不需要android:scaleType【实测会偏大】

六、 RecycleView

1、 android布局用GONE隐藏后不能显示的问题

2、 RecyclerView滚动条_recyclerview 滚动条

3、 添加分割线

  1. RecycleView添加自带分割线
  2. 分割线二

六、Plus 滑动冲突

1、CoordinatorLayout和RecyclerView嵌套滑动冲突解决

  • isNestedScrollingEnabled 有些时候Refreshu嵌在里面监听发现是Recycleview处理的,但UI不生效,用这个试试。

2、Android View 滑动冲突解决方式以及原理

3、Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()

七、ProgressBar(进度条)和SeekBar(拖动条)

1、Android之ProgressBar(进度条)和SeekBar(拖动条

八、Navgation与侧滑DrawerLayout

1、基本使用解说

  1. 选中样式:样式
  2. 详解:DrawerLayout 侧滑栏

九、ToolBar

1、基本使用:细节解说

十、popWindow

PopupWindow最全使用说明

十一、Tablayout

1、Android TabLayout 优雅设置调整指示线tabIndicator 圆角样式和宽度_tablayout tabindicator写法

  • 这种方式颜色不会生效,需要再设定:app:tabIndicatorColor="#008AFF"

十二、Spinner

  • 列选择器

十三、OpenGL

  • 3D图像函数库

十四、RadioButton

十五、SeekBar

十六、TextClock

十七、RemoteViews

  • 蛮常见的,小组件经常会用到,Notification可能会用到
  • 这个View不支持Databinding和ConstraintLayout
  • 在代码中,无法使用FindViewByID,可以用类似setTextViewText这种
  • 不支持设置background
  • 不支持设置Tint

十八、下拉控件Spinner

二:生命周期

1、Android 的singleTask和singleInstance的一点思考

  1. 四种启动模式的特征,onNewIntent会在复用的时候调用。
  2. 关于SingleTask如果设置给最初的入口Activity
  • 如果在当前页按Home键回到桌面再点击APP回来,会优先把栈里的Activity拉起入口Activity,就算被销毁了也会拉起来(销毁拉起来之后不会清除中间的Activity
  • (尽量不要在你的入动(ACTION_MAIN和CATEGORY_LAUNCHER)上使用singleTask,以防其用户点击启动器将你的应用程序带到前台时,在同一taskAffinity中被Android销毁)
  • 如果在 MainActivity 已经存在于任务栈中时启动,MainActivity 会被复用,而位于其之上的其他 Activity 会被清除
  • 如果按任务栏再点击应用会先执行当前页面的onStoped,然后正常onresume,因为没触发App点击图标
  • 如果是singleInstance,不会原本有没有销毁,走APP图标都会把其他的Activity弹出,只剩入口Activity
  • 关于跳Activity清除中间Activity的方法
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

2、 通俗易懂:Handler后传篇一: 为什么Looper中的Loop()方法不能导致主线程卡死?

  1. 常规死循环不会导致anr,anr的原因是死循环后其他需要分发的时间超过了规定时间5s。
  2. Handler死循环中有个判断,如果消息为空会return,阻塞状态。不会分发,取到消息队列后才处理分发。

3、 Android源码—为什么onResume方法中不可以获取View宽高

  1. 一般获取宽高会发现都是0,加个view.post就好了(ps这里面是异步的)。postDelay同理,后面的代码也会先执行;
  2. 文章中说明了oncreate setContentView属于解析xml,执行完Activity的onResume后调用了wm.addView(decor, l)

4、 Android 启动模式FLAG_ACTIVITY_CLEAR_TOP

  1. Intent.FLAG_ACTIVITY_CLEAR_TOP 挺好用的:销毁目标Activity和它之上的所有Activity,重新创建目标Activity。

5、如何在一个Activity里销毁另外一个Activity

6、Kotlin主构造、次构造、init的执行顺序

  • 伴生对象 -> init -> 主构造函数 -> 次构造函数
  • 反编译可以看到效果,PS,Java代码转kotlin,构造函数的方法会默认转进init

7、OnNewIntent的调用时机

8、view的contex一般都是Activity;

9、关于Activity和Fragment的销毁

  • Fragment【存在自身和UI双重生命周期】

    • super.onDestroyView() 前:保存状态、停任务
    • super.onDestroyView() 后:清 UI 引用、解绑 listener
  • Activity

    • 所有清理都在 super.onDestroy() 前做,最后再调用 super.onDestroy()

image.png

image.png

四:四大组件

Activity、Service、Broadcase receiver、Content provider

一、Activity

  • 基础的就不写了 把一些通用的放这里吧

1、Fragment 片段

1、比较Fragment中获取Context对象的两种方法

2、不要直接用构造方法传值(DialogFragment在系统切权限后如果有构造方法会闪退)

  • 解法1:单例类存储
  • 解法2: Viewmodel

2、Intent

1、普通使用

1、装载使用:Android中Bundle传递数据和对象_android bundle传递对象

  • 好处:若有多个Intent装载相同的参数时2,bundle相当于把其抽出装载;
  • intent可以通过传每个intent一直传递activity,bundle也行;
2、PendingIntent

1、PendingIntent理解_者文的博客-CSDN博客

  1. 将某个动作的触发时机交给其他应用或某个View
  2. PendingIntent的使用场景主要用于闹钟、通知、桌面部件

二、Service

1、 Service生命周期总结 | HurryYu

1、启动方式

1、startService【持久后台运行之一】:startService(new Intent(this, MyService.class))

  1. 生命周期
  • 第一次调用startService时,onCreate与OnStartCommand都会被执行;
  • 再继续调用startService方法,只有onStartCommand会被执行(service是单例,重复调用没关系)
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }
  • START_STICKY:如果服务被系统在 onStartCommand() 返回后杀死,系统将重新创建服务并调用 onStartCommand(),但不会重新传递最后的意图。相反,系统会用一个空的意图调用它,除非有挂起的意图启动服务。

  • START_NOT_STICKY:如果服务在 onStartCommand() 返回后被系统杀死,则系统不会重新创建服务,除非有新的明确的服务启动请求

  • 该启动方式,app 杀死、Activity 销毁没有任何影响,服务不会停止销毁;

  • stopService(intent);可按需放在Activity的onDestory中,调用这个就能销毁;

2、bindService【通过Binder控制Service服务】: public boolean bindService(Intent, ServiceConnection, int)

  1. 参数说明:第二参需要传一个监听器(成功连接/断开连接),第三个参数是一个int类型的参数,表示绑定服务的操作选项(一般传入BIND_AUTO_CREATE 自动创建service)
  2. 生命周期:
  • 多次调用,第一次onCreate和onBind执行,后续俩都不执行,且不会回调onServiceConnected;
  • 在Activity的onDestroy生命周期方法中,仍然需要调用unbindService,不然会ServiceConnectionLeaked Crash(必须调用且只能调一次);
  • 客户端 Activity 销毁时, 没有调用 unbindService() 方法 , Service 也会停止销毁;
  • onBind方法中返回一个IBinder接口的实现,而Binder类实现了IBinder接口,因此,我们可以继承Binder类,在类中提供Service与外界的交互方法即可回调onServiceConnected;
2、 两种方式混合启动【持久化控制Servie服务】

1、混合启动的合理性:startService开启后与调用者毫无关联,不会随着调用者的销毁而销毁。bindService可以与调用者绑定实现一些交互,但是与调用者共生死,混合启动可以做到既能提供与调用者的交互,又不会与调用者一起销毁;

2、调用顺序:会影响生命周期:看完这篇Service你还不会,来找我 - 掘金 (juejin.cn)

2、线程说明:

  1. 一个服务(service)运行在 主线程中,服务并不创建自己的线程,也不在隔离进程中运行(除非你指定)。 这意味着,如果你的服务要执行CPU费时操作或阻塞操作,你需要在服务中创建新的线程来执行该操作;

3、前台服务

1、Android startService和bindService混合使用、以及前台服务;_bindservice转换成前台服务

三、Broadcase receiver 广播

1、只在本页面执行的话就在start()和stop()进行注册和销毁【对应,如果重复注册会crash】 2、如果想在后续页面收到的话就在oncreate()和ondestory()进行注册和销毁,设置为主线程的话,activity只要在栈里没销毁,就能更新UI,

四、Content provider

五、上架相关

1、OPPO开放平台过审

六、异常处理

七、概念定义

1、 重写与重载

  1. 覆写/重写:方法名字/参数相同,方法内容不同
  2. 重载:名字相同,参数个数和类型不同

2、并发与并行

  1. 并发:一个处理器同时处理多个任务;逻辑上同时发生;
  2. 并行:多个处理器或多核处理器同时处理多个任务;物理上同时发生;

3、关于boolean类型命名 有些框架序列化方法会自动生成is;话说接口里好像一般用0,1;自己写的方法名有is没关系;

八:系统级

SDK 平台版本说明  |  Android 开发者  |  Android Developers

  • Android 13-API 33
  • Android 9-API 28
  • Android 7.0-API 24

一、清单文件

1、configChanges属性

  1. android:configChanges属性总结_赵凯强的博客-CSDN博客

2、sharedUserId

一般每个apk都具有一个userid,Android会根据userid来给它分配一个Linux用户ID进行管理,并为之创建一个独立沙箱;相同的sharedUserId可以进行资源共享。

3、Android Gradle manifestPlaceholders 的妙用

  1. build配置进manifestPlaceholders

4、明文,密文

1、网络安全配置 明文密文

  1. Android P使用明文明文/密文拓展阅读
  • 配置清单文件那个最暴力好用,实测,Android 12也ok
1、关于android:sharedUserId=“android.uid.system“ 的使用
  1. 声明为系统进程级,享有控制系统权限。
  2. 所用的硬件厂商签名

5、获取App标识包名applicationId

1、Android查看包名和获取包名获取包名_吴庆森的博客-CSDN博客

二、权限

1、Android权限列表permission说明:www.cnblogs.com/jxldjsn/p/6…

2、补充说明

三、 跳转

1、 Kotlin 实现Activity之间的跳转
  • 包含应用内核应用外
  1. startActivity(Intent(this@MainActivity, TestActivity::class.java))
  • kotlin写法:this@MainActivity
  • Java写法:MainActivity.this
2、通过文件唤起应用:

1、参考:android 多媒体文件关联之MIME TYPE_android unsupported mime type audio/*_

四、软键盘: InputMethodManager

1、 软键盘api:Android-软键盘一招搞定(实践篇)

2、 监听状态:Android 监听键盘弹出收起

五、进程保活与杀死

1、进程保活

1、 Android 后台运行白名单,优雅实现保活

2、杀死进程

1、结束当前进程:android.os.Process.killProcess(android.os.Process.myPid());

  • 一般Servie运行在当前进程的主线程中

2、退出Java虚拟机:System.exit(0)

  • 0表示正常退出,1是异常退出
  • 退出虚拟机了,程序运行环境没了,软件也退出了。

六、 app图标控制

1、Android应用图标微技巧,8.0系统中应用图标的适配_guolin的博客-CSDN博客

七、ABI

Application Binary Interface,应用二进制接口:为何大厂APP如微信、支付宝、淘宝、手Q等只适配了armeabi-v7a/armeabi?

1、 想使用native(C/C++) 类库,必须对要支持的处理器架构提供对应编译包。每个处理器架构需要我们提供一个或多个包含native代码的.so文件(支持后会有个文件夹,里面存放多个so库文件)

1、build.gradle里经常能看到适配这些,例如bugly。安卓当前支持七种ABIs

  • mips, mips64, X86, X86–64, arm64-v8a, armeabi, armeabi-v7a
  • 用户可能只需要一种,但代码中写了多少,打包的时候就会打多少,体积浪费;
  • Google支持传多种架构包,支持每个系统下对应的,国内的就一般了。

2、Android NDK配置与详解_ndk.dir

八、微信小程序APP拉起小程序功能 / 功能介绍

九、Google安装器

十、Android之防截屏

  1. 通过window.setFlag即可实现。
  2. 其两个参数设置的值都是一样的,内部是二进制移位操作,嗯,,比较深

十一、Release调试

1、抓包配置文件

image.png 2、打开日志Log:清单文件里 buildtype中release配置:debuggable true

十二、签名

apksigner  |  Android 开发者

1、工具位置

image.png

2、语法

  1. 普通签名相关:
  • --ks 选项指定密钥库文件(.jks)
  • --key 可以指定私钥(.pk8)
  • --cert 可以指定证书文件(.x509.pem)
  1. 轮替签名:支持新的签名文件轮替;

3、通常情况,您只会使用一个 signer 为 APK 签名。如果您需要使用多个 signer 为 APK 签名,请使用 --next-signer 选项将要应用于每个 signer 的常规选项集分隔开

十三、注解

1、Android 注解指南

十四、远程连接控制Android

1、桌面程序

1、Scrcpy工具:adb连接或电脑获取屏幕显示

1、 移动端超级实用工具Scrcpy操作分享

  • 通过ip连接设备并唤起系统桌面,并非针对单一App;

2、网页控制

1、DeviceFarmer

1、 git及安装说明:DeviceFarmer/stf: Control and manage Android devices from your browser. (github.com)

  1. 接入文章参考1[Linux]:搭建设备管理平台-STF(Device Farmer)
  2. 参考2[mac]:基于 STF 的 iOS 远程真机控制,踩坑经验分享
2、ya-webadb/Tango

1、演示文档:探戈 (ya-webadb.vercel.app)

  1. 基于Scrcpy实现;
  2. 数据线可以直接连接查看;
  3. 使用无线需要额外的软件来桥接连接(暂不明)

2、git:yume-chan/ya-webadb: ADB in your browser (github.com)

十五、热修复

1、热修复初探

  1. 两种原理
  2. 目的:下发热补丁包修复bug;

2、实践参考:Android热修复—阿里的新一代热修复技术Sophix

十六、推送

1、友盟

  1. Java 集成Umeng推送/友盟推送 IP不在白名单中, 请到网站后台添加您的服务器IP或关闭IP白名单功能_推送状态关闭或不在白名单内

九:知识库

1、微型知识库
  1. Android性能优化之布局优化 | HurryYu
  2. 记一次 Android 线上 OOM 的排查过程 - 简书 (jianshu.com)