当前位置:首页 » 安卓系统 » androidwait

androidwait

发布时间: 2025-08-09 05:19:02

⑴ 每个Android 都应必须了解的多线程知识点~

进程是系统调度和资源分配的一个独立单位。

在Android中,一个应用程序就是一个独立的集成,应用运行在一个独立的环境中,可以避免其他应用程序/进程的干扰。当我们启动一个应用程序时,系统就会创建一个进程(该进程是从Zygote中fork出来的,有独立的ID),接着为这个进程创建一个主线程,然后就可以运行MainActivity了,应用程序的组件默认都是运行在其进程中。开发者可以通过设置应用的组件的运行进程,在清单文件中给组件设置:android:process = "进程名";可以达到让组件运行在不同进程中的目的。让组件运行在不同的进程中,既有好处,也有坏处。我们依次的说明下。

好处:每一个应用程序(也就是每一个进程)都会有一个内存预算,所有运行在这个进程中的程序使用的总内存不能超过这个值,让组件运行不同的进程中,可以让主进程可以拥有更多的空间资源。当我们的应用程序比较大,需要的内存资源比较多时(也就是用户会抱怨应用经常出现OutOfMemory时),可以考虑使用多进程。

坏处:每个进程都会有自己的虚拟机实例,因此让在进程间共享一些数据变得相对困难,需要采用进程间的通信来实现数据的共享。

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

在Android中,线程会有那么几种状态:创建、就绪、运行、阻塞、结束。当应用程序有组件在运行时,UI线程是处于运行状态的。默认情况下,应用的所有组件的操作都是在UI线程里完成的,包括响应用户的操作(触摸,点击等),组件生命周期方法的调用,UI的更新等。因此如果UI线程处理阻塞状态时(在线程里做一些耗时的操作,如网络连接等),就会不能响应各种操作,如果阻塞时间达到5秒,就会让程序处于ANR(application not response)状态。

1.线程作用

减少程序在并发执行时所付出的时空开销,提高操作系统的并发性能。

2.线程分类

守护线程、非守护线程(用户线程)

2.1 守护线程

定义:守护用户线程的线程,即在程序运行时为其他线程提供一种通用服务
常见:如垃圾回收线程
设置方式:thread.setDaemon(true);//设置该线程为守护线程

2.2 非守护线程(用户线程)

主线程 & 子线程。

2.2.1 主线程(UI线程)

定义:Android系统在程序启动时会自动启动一条主线程
作用:处理四大组件与用户进行交互的事情(如UI、界面交互相关)
因为用户随时会与界面发生交互,因此主线程任何时候都必须保持很高的响应速度,所以主线程不允许进行耗时操作,否则会出现ANR。

2.2.2 子线程(工作线程)

定义:手动创建的线程
作用:耗时的操作(网络请求、I/O操作等)

2.3 守护线程与非守护线程的区别和联系

区别:虚拟机是否已退出,即
a. 当所有用户线程结束时,因为没有守护的必要,所以守护线程也会终止,虚拟机也同样退出
b. 反过来,只要任何用户线程还在运行,守护线程就不会终止,虚拟机就不会退出

3.线程优先级

3.1 表示

线程优先级分为10个级别,分别用Thread类常量表示。

3.2 设置

通过方法setPriority(int grade)进行优先级设置,默认线程优先级是5,即 Thread.NORM_PRIORITY。

4.线程状态

创建状态:当用 new 操作符创建一个线程的时候

就绪状态:调用 start 方法,处于就绪状态的线程并不一定马上就会执行 run 方法,还需要等待CPU的调度

运行状态:CPU 开始调度线程,并开始执行 run 方法

阻塞(挂起)状态:线程的执行过程中由于一些原因进入阻塞状态,比如:调用 sleep/wait 方法、尝试去得到一个锁等

结束(消亡)状态:run 方法执行完 或者 执行过程中遇到了一个异常

(1)start()和run()的区别

通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。调用Thread类调用run()方法来完成其运行操作的,方法run()称为线程体,它包含了要执行的这个线程的内容,run()运行结束,此线程终止,然后CPU再调度其它线程。

(2)sleep()、wait()、yield()的区别

sleep()方法属于Thread类,wait()方法属于Object类。
调用sleep()方法,线程不会释放对象锁,只是暂停执行指定的时间,会自动恢复运行状态;调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池,不调用notify()方法,线程永远处于就绪(挂起)状态。

yield()直接由运行状态跳回就绪状态,表示退让线程,让出CPU,让CPU调度器重新调度。礼让可能成功,也可能不成功,也就是说,回到调度器和其他线程进行公平竞争。

1.Android线程的原则

(1)为什么不能再主线程中做耗时操作
防止ANR, 不能在UI主线程中做耗时的操作,因此我们可以把耗时的操作放在另一个工作线程中去做。操作完成后,再通知UI主线程做出相应的响应。这就需要掌握线程间通信的方式了。 在Android中提供了两种线程间的通信方式:一种是AsyncTask机制,另一种是Handler机制。

(2)为什么不能在非UI线程中更新UI 因为Android的UI线程是非线程安全的,应用更新UI,是调用invalidate()方法来实现界面的重绘,而invalidate()方法是非线程安全的,也就是说当我们在非UI线程来更新UI时,可能会有其他的线程或UI线程也在更新UI,这就会导致界面更新的不同步。因此我们不能在非UI主线程中做更新UI的操作。

2.Android实现多线程的几种方式

3.为何需要多线程

多线程的本质就是异步处理,直观一点说就是不要让用户感觉到“很卡”。

4.多线程机制的核心是啥

多线程核心机制是Handler

推荐Handler讲解视频: 面试总被问到Handler?带你从源码的角度解读Handler核心机制

根据上方提到的 多进程、多线程、Handler 问题,我整理了一套 Binder与Handler 机制解析的学习文档,提供给大家进行学习参考,有需要的可以 点击这里直接获取!!! 里面记录许多Android 相关学习知识点。

⑵ Android性能优化(三)启动速度优化

Android性能优化(三)启动速度优化

一、App启动流程

App的启动流程主要包括以下几个步骤:

  1. 点击桌面App图标:Launcher进程采用Binder IPC向AMS(Activity Manager Service)进程发起startActivity请求。
  2. AMS接收请求:AMS接收到请求后,向zygote进程发送创建进程的请求。
  3. Zygote进程fork新进程:Zygote进程fork出新的子进程,即App进程。
  4. App进程attachApplication:App进程通过Binder IPC向AMS进程发起attachApplication请求。
  5. AMS准备并发送调度请求:AMS进程在收到请求后,进行一系列准备工作,再通过binder IPC向App进程发送scheleLaunchActivity请求。
  6. App进程处理LAUNCH_ACTIVITY消息:App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息。
  7. 主线程创建Activity:主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法。
  8. App启动完成:执行完onCreate/onStart/onResume方法,UI渲染结束后,用户便可以看到App的主界面。

七、启动优化的具体点

  1. 合理使用异步初始化、延迟初始化和懒加载机制:对于不需要在启动时就初始化的资源或功能,可以采用异步初始化、延迟初始化或懒加载机制,以减少启动时的耗时。

  2. 避免启动过程中的耗时操作:如数据库I/O操作等,应尽量避免在主线程执行,可以放在子线程或异步任务中处理。

  3. 类加载优化:通过提前异步执行类加载,可以减少启动时的类加载时间。

  4. 合理使用IdleHandler进行延迟初始化:IdleHandler可以在主线程空闲时执行一些延迟初始化的任务,从而避免在启动时占用主线程时间。

  5. 简化布局:优化布局文件,减少不必要的嵌套和复杂的布局结构,可以提高UI渲染的速度,从而减少启动时间。

通过以上方法,可以有效地优化App的启动速度,提升用户体验。在下一篇文章中,我们将继续探讨Android性能优化的其他方面——卡顿优化。

⑶ android开发中线程有几种状态,分别是哪些

【答案】:1)、新建状态(New):新创建了一个线程对象。
2)、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3)、运行状态(Running):就绪状态的线程获取了CPU,执行run()方法。
4)、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5)、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
当调用start方法的时候,该线程就进入就绪状态。等待CPU进行调度执行,此时还没有真正执行线程。
当调用run方法的时候,是已经被CPU进行调度,执行线程的主要任务。

⑷ android系统中出现的nativecrash反映的是系统哪一层的问题呀是framework层的问题吗

Android平台程序崩溃的类型及原因列举

  1. ANR(可见ANR):

    发生场景:应用发生ANR。

    崩溃症状:系统弹出窗口询问用户选择“Force Close”或者“Wait”。

    "Force Close"将杀掉发生ANR的应用进程。"Wait"将会等待系统择机恢复此应用进程。

    发生原因:(1)应用主线程卡住,对其他请求响应超时。(2)死锁。(3)系统反应迟钝。(4)CPU负载过重。

  2. Force Close:

    发生场景:应用进程崩溃。

    崩溃症状:系统弹出窗口提示用户某进程崩溃。

    发生原因:空指向异常或者未捕捉的异常。

  3. Tombstones:

    发生场景:Native层崩溃

    崩溃症状:如果发生崩溃的native层和UI有关联(比如Browser),我们可以在UI上发现这个崩溃。

    如果发生崩溃的native层是在后台并且和UI没有直接联系,那么对于用户来说是不可见的,如果是debug版本可能会有Log打印出当时的底层现场。

    发生原因:各种各样,需要具体情况具体分析。

  4. 系统服务崩溃(System Server Crash):

    发生场景:系统服务是Android核心进程,此服务进程发生崩溃。

    崩溃症状:手机重启到Android启动界面

    发生原因:(1)系统服务看门狗发现异常。(2)系统服务发生未捕获异常。(3)OOM。(4)系统服务Native发生Tombstone。

  5. Kernel Panics:

    发生场景:Linux内核发生严重错误

    崩溃症状:手机从bootloader开始完全重启

    发生原因:(1)Linux内核内存空间发生内存崩溃。(2)内核看门狗发现异常。(3)空指针操作内核。

⑸ android开发等待一段时间后执行下一条语句,但是thread.sleep(30000)之后线程就挂起了

android的开发思路中,基本上都是由子线程去执行任务的,然后执行完了之后发回message再由handler去处理。这样才不会影响程序连贯性的操作。
你这个需要sleep之后再执行的语句,就放到子线程中去。

⑹ android线程中wait,join,sleep,yield, notify,notifyall,synchronized区别及联系是什么

【答案】:1).sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
2).wait()方法
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
唤醒当前对象锁的等待线程使用notify或notifyAll方法,waite() 和notify()必须在synchronized函数或synchronized block中进行调用。
3).yield方法
暂停当前正在执行的线程对象。yield()只是使当前线程重新回到可执行状态,所以执行3)yield()的线程有可能在进入到可执行状态后马上又被执行。yield()只能使同优先级或更高优先级的线程有执行的机会。
4).join方法
等待该线程终止。等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

⑺ Android 系统运行机制 【Looper】【Choreographer】篇

目录:
1 MessageQueue next()
2 Vsync
3 Choreographer doFrame
4 input

系统是一个无限循环的模型, Android也不例外,进程被创建后就陷入了无限循环的状态

系统运行最重要的两个概念:输入,输出。

Android 中输入 输出 的往复循环都是在 looper 中消息机制驱动下完成的

looper 的循环中, messageQueue next 取消息进行处理, 处理输入事件, 进行输出, 完成和用户交互

应用生命周期内会不断 产生 message 到 messageQueue 中, 有: java层 也有 native层

其中最核心的方法就是 messageQueue 的 next 方法, 其中会先处理 java 层消息, 当 java 层没有消息时候, 会执行 nativePollOnce 来处理 native 的消息 以及监听 fd 各种事件

从硬件来看, 屏幕不会一直刷新, 屏幕的刷新只需要符合人眼的视觉停留机制

24Hz , 连续刷新每一帧, 人眼就会认为画面是流畅的

所以我们只需要配合上这个频率, 在需要更新 UI 的时候执行绘制操作

如何以这个频率进行绘制每一帧: Android 的方案是 Vsync 信号驱动。

Vsync 信号的频率就是 24Hz , 也就是每隔 16.6667 ms 发送一次 Vsync 信号提示系统合成一帧。

监听屏幕刷新来发送 Vsync 信号的能力,应用层 是做不到的, 系统是通过 jni 回调到 Choreographer 中的 Vsync 监听, 将这个重要信号从 native 传递到 java 层。

总体来说 输入事件获取 Vsync信号获取 都是先由 native 捕获事件 然后 jni 到 java 层实现业务逻辑

执行的是 messageQueue 中的关键方法: next

next 主要的逻辑分为: java 部分 和 native 部分

java 上主要是取java层的 messageQueue msg 执行, 无 msg 就 idleHandler

java层 无 msg 会执行 native 的 pollOnce@Looper

native looper 中 fd 监听封装为 requestQueue, epoll_wait 将 fd 中的事件和对应 request 封装为 response 处理, 处理的时候会调用 fd 对应的 callback 的 handleEvent

native 层 pollOnce 主要做的事情是:

vsync 信号,输入事件, 都是通过这样的机制完成的。

epoll_wait 机制 拿到的 event , 都在 response pollOnce pollInner 处理了

这里的 dispatchVsync 从 native 回到 java 层

native:

java:

收到 Vsync 信号后, Choreographer 执行 doFrame

应用层重要的工作几乎都在 doFrame 中

首先看下 doFrame 执行了什么:

UI 线程的核心工作就在这几个方法中:

上述执行 callback 的过程就对应了图片中 依次处理 input animation traversal 这几个关键过程

执行的周期是 16.6ms, 实际可能因为一些 delay 造成一些延迟、丢帧

input 事件的整体逻辑和 vsync 类似

native handleEvent ,在 NativeInputEventReceiver 中处理事件, 区分不同事件会通过 JNI

走到 java 层,WindowInputEventReceiver 然后进行分发消费

native :

java:

input事件的处理流程:

输入event deliverInputEvent

deliver的 input 事件会来到 InputStage

InputStage 是一个责任链, 会分发消费这些 InputEvent

下面以滑动一下 recyclerView 为例子, 整体逻辑如下:

vsync 信号到来, 执行 doFrame,执行到 input 阶段

touchEvent 消费, recyclerView layout 一些 ViewHolder

scroll 中 fill 结束,会执行 一个 recyclerView viewProperty 变化, 触发了invalidate

invalidate 会走硬件加速, 一直到达 ViewRootImpl , 从而将 Traversal 的 callback post choreographer执行到 traversal 阶段就会执行

ViewRootImpl 执行 performTraversal , 会根据目前是否需要重新layout , 然后执行layout, draw 等流程

整个 input 到 traversal 结束,硬件绘制后, sync 任务到 GPU , 然后合成一帧。

交给 SurfaceFlinger 来显示。

SurfaceFlinger 是系统进程, 每一个应用进程是一个 client 端, 通过 IPC 机制,client 将图像显示工作交给 SurfaceFlinger

launch 一个 app:

热点内容
win7svn服务器搭建 发布:2025-09-17 21:01:03 浏览:902
python写shell脚本 发布:2025-09-17 20:50:22 浏览:803
数字存储卡有用吗 发布:2025-09-17 20:31:00 浏览:492
编程有用么 发布:2025-09-17 20:22:01 浏览:161
ftp怎么发文件到服务器 发布:2025-09-17 20:12:14 浏览:145
怎么设置笔记本的密码怎么设置密码 发布:2025-09-17 20:12:12 浏览:318
foxmail上传附件失败 发布:2025-09-17 20:03:54 浏览:361
128服务器是什么意思 发布:2025-09-17 19:49:54 浏览:611
yum安装phpfpm 发布:2025-09-17 19:48:49 浏览:574
斗罗大陆我的世界服务器游戏 发布:2025-09-17 19:46:14 浏览:24