Android基础之容易遗忘点归纳

一:进程等级:

前台进程 (Foreground process)

可见进程 (Visible process)

服务进程 (Service process)

后台进程 (Background process)

空进程 (Empty process)

 

二、Application not responding ANR程序没有响应形成原因:

(1)5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).

(2)BroadcastReceiver在10s内无法结束

(3)Service 20s内无法结束(低概率)

解决方式:

(1)不要在主线程中做耗时的操作,而应放在子线程中来实现。如onCreate()和onResume()里尽可能少的去做创建操作。

(2)应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。

(3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。

(4)service是运行在主线程的,所以在service中做耗时操作,必须要放在子线程中。

 

三、序列化

(1)序列化

由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。

(2)反序列化

反序列化恰恰是序列化的反向操作,也就是说,把已存在在磁盘或者其他介质中的对象,反序列化(读取)到内存中,以便后续操作,而这个过程就叫做反序列化。

概括性来说序列化是指将对象实例的状态存储到存储媒体(磁盘或者其他介质)的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

 

Serializable和Parcelable区别:

01,其中Serializable是Java自带的,而Parcelable是安卓专有的

02,实现方式不同:

Serializable只需要对某个类实现Serializable 接口即可

Parcelable1. 实现Parcelable接口

2. 覆写describeContents方法,默认返回0。

3. 覆写writeToParcel(Parcel dest, int flags)方法,指定写入Parcel类的数据。

4. 创建Parcelable.Creator静态对象,覆写方法createFromParcel(Parcel in)与newArray(int size)。

03,效率不同:

Serializable实现系列号和反序列化,使用反射功能,开销大使用了大量的IO操作

Parcelable是直接在内存中读写,效率更快

 

四:OOAD:

在面向对象分析(OOA)阶段,使用对象建模技术来分析系统的功能需求,并创建反映系统逻辑设计的模型。在系统的面向对象设计(OOD)阶段,模型被详细描述,包括实现特定细节,显示系统的物理设计将如何组合在一起。 OOA关注系统做什么(静态结构和行为),OOD关注系统如何做(它的运行实现)

 

五,怎么判断前后台

1 、RunningTask方法,android5以后废弃了

2、RunningAppProcessInfo 方法(本人习惯使用)

public static boolean isBackground(Context context) {

ActivityManager activityManager = (ActivityManager) context

.getSystemService(Context.ACTIVITY_SERVICE);

List appProcesses = activityManager

.getRunningAppProcesses();

for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {

if (appProcess.processName.equals(context.getPackageName())) {

if (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){

Log.i(context.getPackageName(), "处于后台" + appProcess.processName);

return true;

} else {

Log.i(context.getPackageName(), "处于前台"+ appProcess.processName);

return false;

}

}

}

return false;

}

3、ActivityLifecycleCallbacks 方法

4、UsageStatsManager方法、打开手机设置,点击安全-高级,在有权查看使用情况的应用中,为这个 App 打上勾

方法五:通过 Android 自带的无障碍功能

6、方法六:读取 Linux 系统内核保存在/proc 目录下的 process 进程信息

 

六:sdk和Ndk:

SDK:(softwaSDK:(software development kit)软件开发工具包。被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合,Android SDK 指的是Android专属的软件开发工具包。

NDK: 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。

众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。

NDK包括了:

  • 从C / C++生成原生代码库所需要的工具和build files。
  • 将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files ,即.apk文件)中。
  • 支持所有未来Android平台的一系列原生系统头文件和库

为何要用到NDK?

概括来说主要分为以下几种情况:

1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库被反编译的难度较大。

2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。

3. 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。

 

七:jar 和 aar:

jar:包含了class文件与清单文件 ,不包含资源文件,如图片等所有res中的文件。

aar:Android库项目的二进制归档文件,包含所有资源,class以及res资源文件全部包含。

 

八,android不同版本特性

Android8 特性:通知通道,PIP画中画模式,自定义图标,快捷小部件

Android9特性:动态电池管理,黑暗模式,权限更加安全

Android10特性:1、主要是隐私方面加强,比如不能获取getDeviceId

2、支持5g

 

九:socket与http区别:Http连接:http连接就是所谓的短连接,及客户端向服务器发送一次请求,服务器端相应后连接即会断掉。socket连接:socket连接及时所谓的长连接,理论上客户端和服务端一旦建立连接,则不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该链接已释放网络资源。所以当一个socket连接中没有数据的传输,那么为了位置连续的连接需要发送心跳消息,具体心跳消息格式是开发者自己定义的

 

十:自定义桌面:

1、想将home screen换成自己写的activity,该如何实现?

在你要设置为home screen的那个activity的androidManifest.xml中的标签中加上这几句 话

运行后,重启模拟器会弹出一个选择进入哪个界面的对话框

2、怎样将系统默认的home screen删除?

重新编译launcher源码,去掉配置文件中的home属性和HOME属性。。

在自己的activity中加入这两个属性,然后重新烧系统。 

 

十一、 Handler线程池原理,引用过程:

01、 handler是安卓给我们提供用来更新UI的一套机制,也是消息处理的一套机制,我们可以发送消息,也可以处理消息

02、 为什么使用handler:当在线程中更新UI会报错

03、 handler主要方法 1.handler.post 2.handler.postDelayed (带延迟时间的post方法) 3,handler.sendmessage 发送消息方法 4,handler.removecanllback 删除runnable线程方法

5、handler h = new handler(new callback) 带返回值的handlermessage 方法,当这个方法return false,则会再执行,不带返回值的handlermessage 方法,当return true则不再往下执行

04、handler解决了什么问题:核心就是解决UI并发问题

001、多个线程更新UI,并且都没加锁,会出现界面错乱的问题

002、如果多线程更新UI,都加锁,会出现性能下降的问题

所以通过hendler返回在主线程中更新UI

05、handler原理是什么:

handler 封装了消息的发送

looper,是消息的一个轮询的载体,内部包括messagequeue(消息队列),所有handler发送的消息都是发送到这个消息队列

looper.looper方法,是一个死循环,不断从messagequeue取消息,如有消息就处理,没有就阻塞

messagequeue 是消息队列,可以添加消息和处理消息,是一个存储信息的容器

handler也简单,内部会跟looper相关,也就是说handler的内部可以找到looper,找到looper也就找到了messagequeue,handler发送消息就是发送到messagequeue

threadlocal:是一个在线程当中去保存变量信息的类,有set 和get 方法

activitythread:整个应用程序的activiy都是通过这个方法创建;

启动和关联原理,activitythread这个类的main中创建所有应用程序和各种UI,也创建looper方法(调用threadlocal的get方法去获取looper,如果没有则新建,在set到threadlocal中),创建new looper方法中也创建了new messagequeue

关联原理:在handler方法中looper.mylooper方法,mylooper方法实现方式是threadlocal.get方法,再通过looper拿到meaasgequeue

发送消息和回调原理:1、发送原理:handler.sendmessage 方法中会调用 sendmessageaAtTime方法,这个方法中会获取messagequeue,就把消息发送到这个消息队列当中 2、回调原理:looper.looper方法,通过mylooper方法获取looper,再获取messagequeue消息队列,再通过for(::)死循环来遍历messagequeue队列,有消息就通过 dispatchmessage来回调,dispatchmessage方法实现原理,先去判断messag.callback方法是否为空,不为空调用handlecall方法回调,如果为空调用 handlemessage方法回调

 

handlerthread 原理详解:handlerthread 继承thread,本质是线程handlerthread.getlooper方法实现,判断线程是否或者,再判断looper是否存在,不存在就wait等待,在run方法中,会去创建looper对象looper.mylooper,然后notifyall,去唤醒等待中的线程对象,handler就能获取到looper对象,就不会报空指针的异常

handlerthread 应用场景:默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。),HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper,将loop转到子线程中处理

参开文档:https://www.cnblogs.com/zhaoyanjun/p/6062880.html

 

十二、线程和进程的区别

首先一点,进程是包含线程的。就是一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。而一个运行的软件是可以包含多个进程的。线程是码顺序执⾏行行下来,执⾏行行完毕就结束的一条线。

线程和进程的具体区别如下:

进程是资源分配的最小单位,线程是程序执行的最小单位。

进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。

但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间

 

十三、安卓多线程安全:

1、UI线程安全:01、耗时操作不在UI线程,否则会引发NAR,影响用户体验

02、 UI非线程安全,不在其他线程操作UI。

2、数据库线程安全:SQLiteOpenHelper 写成单例模式

3、文件线程安全:对文件操作单独写个类,进行读写时进行同步处理

4、synchronized:所以其只同步对象,当一个线程执行这个对象同步方法时,其他线程无法执行这个对象的任何同步方法或代码。因为所有同步方法执行前都要获取对象的同步锁。

 

 

十四、内存溢出,内存泄漏,内存抖动的区别,以及内存溢出的解决方法:

区别:

内存溢出(Out of Memory):系统会给每个APP分配内存也就是Heap Size值。当APP占用的内存加上我们申请的内存资源超过了Dalvik虚拟机的最大内存时就会抛出的Out Of Memory异常。

内存泄漏(Memory Leak):当一个对象不在使用了,本应该被垃圾回收器(JVM)回收。但是这个对象由于被其他正在使用的对象所持有,造成无法被回收的结果。内存泄漏最终会导致内存溢出。

内存抖动:内存抖动是指在短时间内有大量的对象被创建或者被回收的现象,主要是循环中大量创建、回收对象。这种情况应当尽量避免。

它们三者的重要等级分别:内存溢出 > 内存泄露 > 内存抖动。

解决方法:

1、不要在主线程中处理图片

2、使用bitmap要recycle回收

3、控制图片的大小,压缩大图,高效处理,加载合适属性的图片

4、在Activity中创建非静态内部类,非静态内部类会持有Activity的隐式引用,若内部类生命周期长于Activity,会导致Activity实例无法被回收,尽量不要使用创建内部类,如果一定要使用内部类,就改用static内部类,在内部类中通过WeakReference的方式引用外界资源。

5、对于使用了BraodcastReceiver,ContentObserver,Cursor,File,Stream,ContentProvider,Bitmap,动画,I/O,数据库,网络的连接等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

6、static对象的生命周期过长,应该谨慎使用。一定要使用要及时进行null处理。

7、如果使用Context ,尽可能使用Applicaiton的Context,单例模式造成的内存泄漏,如context的使用,单例中传入的是activity的context,在关闭activity时,activity的内存无法被回收,因为单例持有activity的引用

8、不要使用String进行字符串拼接

9、对于EventBus,RxJava等一些第三方开源框架的使用,若是在Activity销毁之前没有进行解除订阅将会导致内存泄漏

10、在onPause()/onDestroy()方法中解除监听器,包括在Android自己的Listener,Location Service或Display Manager Service以及自己写的Listener

 

十五:热更新:1、无需重新发版,及时修复问题

2、 用户无感知修复,无需下载新应用,代价小

3、 修复成功率高,把损失降到最低

实现方案:腾讯的 tinker ,bugly中集成tinker ,可以实现热更新

 

 

十六:Web网页优化:

为什么要进行网页优化:

而用户的耐心是有限的,如果几秒钟之内页面仍是白屏,很有可能就会关闭此页面,那么页面功能再酷炫,再强大也没用。而通常情况下,公司的活动页往往都用H5来实现,因此如果页面展现速度过慢的话,还会造成公司损失

1、Webview所有的逻辑处理都是通过WebViewProvider来实现的,因为它要加载Webview内核,这是一个重量级的操作,内核是以apk的形式存在。而内核加载后在同一页面是共享的,因此后续的初始化时间就很少了。我们可以在App生成一个全局webview,并且在启动时初始化,这样在后面使用时通过动态获取这个全局Webview,然后添加到rootview中,这样就可以进行复用从而减少初始化的时间。

2、对于H5页面来说,图片资源的拉取是最为耗时的,一个比较好的解决方案就是先加载并展示非图片内容,延迟这些图片的加载,以提升用户体验

3、创建webview需要使用applicationContext而不是activity的context

4、webview支持saveState(bundle)和restoreState(bundle)方法,在关闭的时候保存网页状态

 

 

十七:安卓缓存机制:

主存储器

又称内存是CPU能直接寻址的存储空间,它的特点是存取速率快。内存一般采用半导体存储单元,包括随机存储器(Random Access Memory)、只读存储器(Read Only Memory)和高级缓存(Cache)。

  • RAM:随机存储器可以随机读写数据,但是电源关闭时存储的数据就会丢失;
  • ROM:只能读取,不能更改,即使机器断电,数据也不会丢失
  • Cache:它是介于CPU与内存之间,常用有一级缓存(L1)、二级缓存(L2)、三级缓存(L3)(一般存在于Intel系列)。它的读写速度比内存还快,当CPU在内存中读取或写入数据时,数据会被保存在高级缓冲存储器中,当下次访问该数据时,CPU直接读取高级缓冲存储器,而不是更慢的内存。

辅助存储器

辅助存储器又称外存储器,简称外存,对于电脑而言,通常说的是硬盘或者光盘等,对于手机一般指的是SD卡,不过现在很多厂商都已经整合在一起了

内存泄露

这个主要发生在内存缓存中,当生命周期段的对象持有了生命周期长的对象的引用就会发生内存泄露,解决这种问题通常有两种方式

  • 引用置空:将缓存中引用的对象置空,然后GC就能够回收这些对象
  • 采用弱引用:采用弱引用关联对象,这样就能够不干涉对象的生命周期,以便GC能够正常回收

 

18、逆编码:apktool工具

19、volley网络请求框架:

volley是什么:是安卓平台上的网络通讯库

volley特点:1、通讯更快更便捷

2、支持get,post网络请求和网络图像的高效率的异步请求

3、支持请求优先级排序

4、支持网络请求缓存

5、多级别取消请求

6、和activity生命周期的联动

volley缺点:不适合数据的上传和下载

为什么选择volley:

1、高效率的get,post请求

2、网络图片加载和缓存

3、谷歌官方的网络框架,性能稳定和强劲

volley数据返回格式:

1、stringrequest(包含后两种,在返回数据不确定情况下使用)

2、jsonobjectrequest(返回jsonobject情况下使用)

3、jsonarrayrequest(返回jsonarray情况下使用)

加载图片: imagrequest方式请求,加载方法中,可以设置图片长宽,格式,请求成功返回

使用流程:1、在application 注册全局的 volley

2、在请求过程中,输入相对应的参数后,获取全局的volley,输入tag做标记,再启动,请求成功或者失败,都有相对应的返回情况

3、注销activity的时候,调用removeall,根据tag删除这个请求队列

20、性能优化之图片优化:

1、图片压缩:1、WEBP格式,既支持透明,也支持压缩

2、质量压缩,用RGB_565来代替 ERGB_8888可以降低图片占用内存

3、Inbitmap来实现内存重用,条件是后面的图占用内存要小于等于前面的图

21.retrofit:

什么是retrofit:是square公司基于RESTful风格推出的网络框架封装

retrofit和okhtp的关系:retrofit是基于okhttp的网络请求框架的二次封装,本质是okhttp

retrofit和其他网络库的对比:volley不合适大数据量的文件的上传和下载

retrofit特点:注释化配置,支持rxjava,支持多种解析

 

22、wifi调试:https://jingyan.baidu.com/article/db55b6092650a24ba30a2f13.html

 

你可能感兴趣的:(Android基础之容易遗忘点归纳)