Android 中等面试题

反射中,Class.forName和classloader的区别

class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容

  • App进程保活

1.利用Activity
1像素Activy,监控手机解锁屏事件,解锁时将Activity销毁,锁屏时启动,并且要无感知,在RecentTask里移除
2.监听系统静态广播
低版本时,静态广播可以唤醒应用进程,所以监听系统广播,例如开机,锁屏,解锁等可以做到,但是高版本不能通过静态广播监听系统广播了
3.利用系统Service机制拉活
Service 的 onStartCommand 返回值,当返回值为 START_STICKY 和 START_REDELIVER_INTENT 时,服务会自动重启,但是 Service 在短时间内被杀死5次,则不再拉起
4.使用WorkManager定时任务定时调起App。
5.利用账号同步机制
Android 系统的账号同步机制会定期同步账号进行,该方案目的在于利用同步机制进行进程的拉活。添加账号和设置同步周期的代码即可

  • 如何保证service在后台不被kill?

利用的系统广播是Intent.ACTION_TIME_TICK,这个广播每分钟发送一次,我们可以每分钟检查一次Service的运行状态,ActivityManager.getRuningServices()获取所有活动的service,根据名字用equals判断其中没有这个service了,就重新启动Service。

  • 描述请点击 Android Studio 的 build 按钮后发生了什么

参考:App 的编译和打包流程

  • 权限管理底层的权限是如何进行 grant 的

参考

  • App消息推送原理是什么?

在Android开发中,app消息推送的基本原理就是要在推送服务器和客户端之间建立连接,而连接的建立方式主要有两种pull和push。在实践过程中我们发现,相较于通过轮询(pull)的方式来获得消息通知,建立长连接(push)进行推送无论是对用户终端的电量消耗,还是对云端数据访问流量的耗费都比轮询要好,因此目前主流的app消息推送基本都是通过push的方式实现的。
推送的实现技术简单来说就是利用Socket维持Client和Server间的一个长连接。
实现消息推送可以有客户端轮询访问;SMS短信推送;Xmpp协议推送等。

  • JNI开发中怎么定位native crash

可使用add2line 和ndk-stack等工具分析JNI Crash的log。
参考:https://www.jianshu.com/p/e5d357f12f83

什么是dump文件

从软件开发的角度上,dump文件就是当程序产生异常时,用来记录当时的程序状态信息(例如堆栈的状态),用于程序开发定位问题,文件后缀为.DMP。dump文件可以利用WinDbg打开,也可以直接用vs打开。

上图给出NativeCrash收集的整体实现方案。APP中接入提供的SDK,包含一个通用SO和一个JAR,当APP中发生NDK崩溃时,会在手机端生成一个dmp文件,待下次APP重启后,将此dmp文件上传至服务端,在服务端进行解析、分类、聚合、可读展示等过程。

如果项目接入了Bugly,也就可以收集到NativeCrash上传至Bugly。

mainfest中配置LargeHeap,真的能分配到大内存吗?能增加多大内存?

设置android:largeHeap="true"属性之后,进行如下测试查看最大可用内存,发现最大可用内存真的增大了。但是最大不能超过系统能分配给App的最大内存。

ActivityManager.getLargeMemoryClass()  //可以获得开启largeHeap最大的内存大小
  • 谈谈你对 Activity.runOnUiThread 的理解?

runOnUiThread过程源码

// Activity.java
public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }
}

// Handler.java
public final boolean post(@NonNull Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

首先判断当前是不是 UI线程,如果是就直接执行传入的Runnable接口的run方法。
否则就通过Activity类中的Handler实例的post(Runnable)方法来发送消息,最终调用handler的enqueueMessage方法将任务加入到消息队列中,因为在Activity中的Handler对象运行在主线程(主线程中的Handler对象是在ActivityThread类中的main方法中创建的),故而这里就切换到了主线程中。

Intent传输数据的大小有限制吗?如何解决?

Intent传输数据的大小受Binder的限制,上限是1M。不过这个1M并不是安全的上限,Binder可能在处理别的工作,安全上限是多少这个在不同的机型上也不一样。

传 512K 以下的数据的数据可以正常传递。
传 512K~1024K 的数据有可能会出错,闪退。
传 1M以上的数据会报错:TransactionTooLargeException
考虑到 Intent 还包括要启动的 Activity 等信息,实际可以传的数据略小于 512K

解决办法
减少传输数据量
Intent通过绑定一个Bundle来传输,这个可以超过1M,不过也不能过大
通过内存共享,使用静态变量或者使用EventBus等类似的通信工具
通过文件共享

  • 线上报错查日志怎么使用mapping文件

mapping.txt文件位于app模块根目录下,它是混淆前方法和字段名与混淆后代码间的映射。比如在bugly上有崩溃日志定位不到类和方法,需要上传mapping文件来处理。
线上崩溃有崩溃日志,但是是混淆之后的报错堆栈,需要在Jenkins上下载当次打包生成的mapping文件进行查询报错位置。

  • ksp与kapt的区别

注解处理器是Android开发中一种常用的技术,很多常用的框架比如ButterKnife,ARouter,Room中都使用到了注解处理器相关技术。
ksp(Kotlin Symbol Processing),一款专门拿来给Kotlin项目提升注解生成速度的,需继承SymbolProcessor来自定义注解处理器。

总结KSP优点:
KSP性能更好,有时可以达到2倍的速度提升;
KSP开发起来更加方便,不需要自己处理增量编译逻辑;
KSP支持多平台,而KAPT只支持JVM平台
KSP拥有更符合Kotin习惯的API,同时可以识别Kotin特有的符号

参考:
https://juejin.cn/post/6939472660573192206
https://juejin.cn/post/7116305314529411085

Android 13有哪些需要适配的地方

首先将我们项目中的 targetSdkVersion和compileSdkVersion 升至 33。
1.通知受限
对新安装的应用的影响:
如果用户在搭载 Android 13 或更高版本的设备上安装您的应用,应用的通知默认处于关闭状态。在您请求新的权限且用户向您的应用授予该权限之前,您的应用都将无法发送通知。

适配方法:
应用以Android 13或更高版本为目标平台,需要在应用程序manifest文件中声明POST_NOTIFICATIONS权限,并完成与请求其他运行时权限类似的流程。

 <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

2.读取媒体文件权限
对于目标版本为Android 13的应用,细化了READ_EXTERNAL_STORAGE权限,使用READ_MEDIA_IMAGE、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO替代READ_EXTERNAL_STORAGE。

如果用户之前向您的应用授予了 READ_EXTERNAL_STORAGE 权限,系统会自动向您的应用授予细化的这三个媒体权限。

<manifest ...>
    <!-- 按需添加 -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
                     android:maxSdkVersion="32" />
</manifest>

参考:
https://blog.csdn.net/qq_17766199/article/details/130520330

用RecyclerView怎么实现首页复杂列表页面

关键做法:
根据GridLayoutManager的getSpanSize()方法可以动态的设置item跨列数。
例如:
根据getItemViewType返回的itemtype,第一个position显示为轮播图,
所以返回的是gridManager.getSpanCount(); 即:return 6
如果是2张图占满一行,那么1张图就是占整行的二分之一,既6/2=3, return 3即可。

参考代码:

adapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() {
            @Override
            public int getSpanSize(GridLayoutManager gridLayoutManager, int position) {
                int type = data.get(position).getType();
                if (type == 1 || type == 3 || type == 2 || type == 5 || type == 6) {
                    return 6;
                } else if (type == 4) {
                    return 2;
                } else if (type == 7) {
                    return 3;
                }
                return 0;
            }
        });

参考:
https://juejin.cn/post/6939822591515295781

sealed class 是什么,跟Enum的区别是什么?

密封类sealed:
Human模型数据结构,Man、Woman分别是子类。
name、age是Human共有的属性,a1、a2是Man特有的属性,而a3、a4则是Woman特有的。

sealed class Human(val name: String, val age: Int) {
    class Man(name: String, age: Int, val a1: Int, val a2: Int) : Human(name, age)
    class Woman(name: String, age: Int, val a3: Int, val a4: Int) : Human(name, age)
}

    //处理
    fun handleHuman(human: Human) {
        when (human) {
            is Human.Man -> {
                //type 为man的处理
                Log.d("test",human.a1.toString() + human.a2.toString())
            }
            is Human.Woman -> {
                //type 为woman的处理
                Log.d("test",human.a3.toString() + human.a3.toString())
            }
        }
    }
  • 密封类适合用在父类定义共同属性,子类具有特殊属性的场景,这点跟枚举不一样,密封类sealed算是枚举的增强;
    当密封类sealed用于类型判断,when少了对应的类型处理(定义了3种,只处理了2种),编译期会有提示,也是很友好的。
    密封类以及它的子类最好都定义在同一个文件中,这样会更加内聚。

参考:https://juejin.cn/post/7088232943142830087

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 所有知识点已整理成app app下载地址 J2EE 部分: 1.Switch能否用string做参数? 在 Jav...
    侯蛋蛋_阅读 2,424评论 1 4
  • 别人的总结不一定适合自己,所以尽量多做一些自己的总结,针对自己的薄弱点重点说明,适当的借鉴别人,少走一些弯路。最重...
    renkuo阅读 7,401评论 2 48
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,699评论 0 11
  • 大家好,我是来自B队亚茹组的乔静,是一名平面设计师和产品运营,很高兴跟大家相识在演讲社群。 我是一个性格偏内向不太...
    乔静_静姐Jane阅读 304评论 0 0