Android随手记

news2024/12/26 17:33:06

activity的生命周期

创建时

onCreate() - onStart() - onResume() - onPause() - onStop() - onDestroy()

切换时

a切换到b
a.onCreate() - a.onStart() - a.onResume - a.onPause - b.onCreate() - b.onStart() - b.onResume() - a.onStop()
b切换回a
b.onPause() - a.onRestart() - a.onStart() - a.onResume() - b.onStop() - b.onDestory()

Handler相关

Handler是什么

一句话总结:Handler是用于与跨线程通信的,而每个线程都有自己的looper,looper管理线程的任务,所以其实Handler就是用于与looper通信的,在Handler里装哪个looper,最终代码就在哪个线程上跑

Looper

Looper的ThreadLocal

Looper内部有个成员变量sThreadLocal<Looper>,用于在不同的线程获取不同(每个线程独有的)looper

Looper.prepare()的内部其实是sThreadLocal.set(new Looper),就是创建一个新的looper,set到当前线程里去,以后在这个线程里拿的looper就是这里来的

Looper.myLooper()的内部是sThreadLocal.get(),就是去get了一下之前set的looper

Android开机流程

在这里插入图片描述

电源键

按下电源键后,引导芯片代码从固化在ROM中的地方开始执行,加载引导程序BootLoader到RAM中,然后执行

BootLoader

BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。

Kernel

Android内核启动时,会设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init.rc”文件,然后启动init进程

init

init进程是第一个用户空间的进程,也就是第1号进程(第0号进程是linux)
init进程在system/core/init/main.cpp文件的main函数中,分为两个阶段完成启动过程
第一阶段时进行一些目录创建、设备节点创建和设备挂载的动作(毕竟Android跑在linux上)
第二阶段启动属性服务(指定文件读取属性、系统属性等)、解析init.rc文件并启动相关进程
其中第二阶段的init.rc不止一份,例如google、soc、odm厂商都有自己的init.rc

Zygote

Zygote进程由init进程启动,他是Android系统的第一个进程(pid为0)
init拉起Zygote的简化代码如下

Result<void> Service::Start() {
    ...
    pid_t pid = -1;
    if (namespaces_.flags) {
        pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
    } else {
        pid = fork();// 1.fork创建service进程(也就是zygote进程)
    }
    if (pid == 0) {
        ...
        if (!ExpandArgsAndExecv(args_, sigstop_)) {
            PLOG(ERROR) << "cannot execv('" << args_[0]
                        << "'). See the 'Debugging init' section of init's README.md for tips";
        }
        ...
    }
}

可以看到,Zygote由init进程fork(创建父进程的子进程)而来(估计是在linux虚拟机里创建,所以pid为0?),下面的ExpandArgsAndExecv用于指定Zygote的执行路径

所有的应用程序进程以及系统服务进程(SystemServer)都是由Zygote进程孕育(fork)出来的,zygote本身是Native应用程序,与驱动内核无关。

Zygote主要工作有两个
1、启动socket服务,监听socket,响应启动应用请求,有app点开的时候socket服务端会fork生成新的app进程(Dalvik虚拟机)
2、启动systemserver

SystemServer

启动各种系统服务,例如上下文管理器、电池服务、窗口管理器等

Android四层架构

应用程序层
应用框架层
类库层
linux内核

synchronized加锁

首先明确,synchronized锁住的对象都是final的,也就是说如果我们对class中的某个函数加synchronized关键字,其实锁住的是这个class(例子中锁住的是StopThread.class),例如
在这里插入图片描述
这段代码中,有两个函数都被添加了synchronized关键字,那么不管有多少对象(线程)调用这两个函数其中的任意一个,同一时间只有一个函数会被执行(毕竟底层是用class.fun(),这个class被锁住了那么就只有一个fun能被执行),也就是说这个class中不管有多少函数被添加了synchronized关键字,同一时间执行的函数都只能有一个,这种做法其实会导致代码效率降低

Service和IntentService

Service

当应用组件通过startService方法来启动Service 时,Service 则会处于启动状态(跑在主线程),一旦服务启动,它就会在后台无限期的运行,生命周期独立于启动它的组件,即使启动它的组件已经销毁了也不受任何影响(除非手机内存要满了,被系统杀掉),通过这种方式启动的服务不好与组件之间通信

一般来说,我们想要Service的服务,会通过bindService来启动

如果服务和用户在一个进程内,直接让Service回传一个Binder就行了

public class MusicService extends Service implements IPlayer{
    public static final String TAG = "MusicService";
    private LocalService mBinder = new LocalService();
    public class LocalService extends Binder{
        public MusicService getService(){
            return MusicService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void play() {
        Log.i(TAG,"music play...");
    }

    @Override
    public void pause() {
        Log.i(TAG,"music pause...");
    }

    @Override
    public void stop() {
        Log.i(TAG,"music stop...");
    }

    @Override
    public int getProgress() {
        return 100;
    }

    @Override
    public int getDuration() {
        return 10240;
    }
}

这样用户在bindService的时候,用ServiceConnection拿到回传的binder就可以调用服务的能力了

如果服务和用户不在同一个进程,用AIDL就行
在服务端和用户端都新建统一的AIDL,在服务端实现AIDL,然后在onBind()函数里回传这个AIDL.stub()
用户端在ServiceConnection里拿到回传的binder也一样可以调用服务的能力了

IntentService

Service默认是跑在主线程上的,并且如果不手动关闭的话就要等系统回收,而IntentService是跑在其他线程上的,并且在他的任务执行完毕后,就自动停止了

public class MyIntentService extends IntentService {
    public static final String TAG ="MyIntentService";
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
      // 这里已经是工作线程,在这里执行操作就行

       boolean isMainThread =  Thread.currentThread() == Looper.getMainLooper().getThread();
        Log.i(TAG,"is main thread:"+isMainThread);

        // 执行耗时下载操作
        mockDownload();
    }

    /**
     * 模拟执行下载
     */
    private void mockDownload(){
       try {
           Thread.sleep(5000);
           Log.i(TAG,"下载完成...");
       }catch (Exception e){
           e.printStackTrace();
       }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1508116.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp:小程序数字键盘功能样式实现

代码如下&#xff1a; <template><view><view><view class"money-input"><view class"input-container" click"toggleBox"><view class"input-wrapper"><view class"input-iconone"…

信息系统项目管理师--成本管理

项⽬成本管理重点关注完成项⽬活动所需资源的成本&#xff0c;但同时也考虑项⽬决策对项⽬产品、服务或成果的使⽤成本、维护成本和⽀持成本的影响。不同的⼲系⼈会在不同的时间&#xff0c;⽤不同的⽅法 测算项⽬成本。 就某些项⽬&#xff0c;特别是⼩项⽬⽽⾔&#xff0c;成…

鸿蒙操作系统 HarmonyOS 3.2 API 9 Stage模型通过ArkTS接入高德地图

用鸿蒙ArkTS语言开发地图APP应用时&#xff0c;很多地图厂商只接入了鸿蒙Java&#xff0c;ArkTS版本陆续接入中&#xff0c;等一段时间才能面世&#xff0c;当前使用地图只能通过鸿蒙的Web组件&#xff0c;将HTML页面嵌入到鸿蒙APP中。具体方法如下&#xff1a;编写HTML <!…

【Linux】Shell及Linux权限

Shell Shell的定义 Shell最简单的定义是&#xff1a;命令行解释器。 Shell的主要任务&#xff1a;1. 将使用者的命令翻译给核心进行处理。2.将核心的处理结果翻译给使用者 为什么要有Shell? 使用者和内核的关系就相当于两个完全陌生的外国人之间的关系&#xff0c;他们要进…

酒店客房管理系统|基于Springboot的酒店客房管理系统设计与实现(源码+数据库+文档)

酒店客房管理系统目录 目录 基于Springboot的酒店客房管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、 用户信息管理 2、会员信息管理 3、 客房信息管理 4、收藏客房管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机…

【Vue】.sync 修饰符作用

文章目录 基本用法 基本用法 官方文档是这样介绍的&#xff1a;.sync 修饰符 简单来说就是实现父子组件数据之间的双向绑定&#xff0c;当子组件修改了一个 props 的值时&#xff0c;也会同步到父组件中&#xff0c;实现子组件同步修改父组件&#xff0c;与v-model类似。类别在…

Redis分段锁,如何设计?

问题场景&#xff1a;热点库存扣减问题 秒杀场景&#xff0c;有一个难度的问题&#xff1a;热点库存扣减问题。 既要保证不发生超卖 又要保证高并发 如果解决这个高难度的问题呢&#xff1f; 答案就是使用redis 分段锁。 什么是分布式锁&#xff1f; 一个分布式系统中&am…

SSM整合项目(使用Vue3 + Element-Plus创建项目基础页面)

1.配置Vue启动端口 1.修改vue.config.js const {defineConfig} require(vue/cli-service) module.exports defineConfig({transpileDependencies: true }) module.exports {devServer: {port: 9999 //启动端口} }2.启动 2.安装Element Plus 命令行输入 npm install eleme…

老阳推荐的视频号带货蓝海项目靠谱吗?

近年来&#xff0c;随着短视频平台的崛起&#xff0c;视频号带货逐渐成为了一个热门的新兴行业。在这个领域里&#xff0c;不少专家和达人纷纷涌现&#xff0c;其中老阳就是备受关注的一位。他推荐的视频号带货蓝海项目吸引了众多眼球&#xff0c;但这样的项目究竟靠不靠谱呢?…

【小黑送书—第十二期】>>一本书讲透Elasticsearch:原理、进阶与工程实践(文末送书)

Elasticsearch 是一种强大的搜索和分析引擎&#xff0c;被广泛用于各种应用中&#xff0c;以其强大的全文搜索能力而著称。 不过&#xff0c;在日常管理 Elasticsearch 时&#xff0c;我们经常需要对索引进行保护&#xff0c;以防止数据被意外修改或删除&#xff0c;特别是在进…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《含海上风电制氢的综合能源系统分布鲁棒低碳优化运行》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【网络】数据在同网段和跨网段通信流程

情景一&#xff1a;同一广播域内&#xff0c;两台主机通信过程&#xff1a; 当NO要和N1通信时&#xff0c;假如N0知道N1的IP但却不知道它的MAC地址&#xff0c;那NO就会发送一个ARP的广播请求<1>&#xff08;里面源IP是NO 目标IP是N1 源MAC是N0 目标MAC是12个F&#xff0…

Python 分析— 使用 LeuvenMapMatching 包进行地图匹配用于道路导航

在道路导航中,我们有了街道网络地图。轨迹/GPS 数据必须与街道相匹配才能进行导航,因为 GPS 读数提供纯粹的纬度和经度坐标,但我们想知道车辆行驶的具体道路。 我首先尝试了一种简单的方法来匹配点,将每个点独立地匹配到最近的路段。如果没有道路,只需扩大缓冲距离…

耐腐蚀特氟龙塑料材质PFA烧杯超纯试剂反应杯

PFA烧杯在实验过程中可作为储酸容器或涉及强酸强碱类实验的反应容器&#xff0c;用于盛放样品、试剂&#xff0c;也可搭配电热板加热、蒸煮、赶酸用。 外壁均有凸起刻度&#xff0c;直筒设计&#xff0c;带翻边&#xff0c;便于夹持和移动&#xff0c;边沿有嘴&#xff0c;便于…

amv是什么文件格式?如何播放amv视频?

AMV文件格式源自于中国公司Actions Semiconductor&#xff0c;最初作为其MP4播放器中使用的专有视频格式。产生于数码媒体发展的需求下&#xff0c;AMV格式为小屏幕便携设备提供了一种高度压缩的视频存储方案。 AMV文件格式的主要特性与使用场景 AMV格式以其独特的特性在小尺寸…

SpringCloudAlibaba 网关gateway整合sentinel日志默认路径修改

SpringCloudAlibaba 网关gateway整合sentinel 实现网关限流熔断 问题提出 今天运维突然告诉我 在服务器上内存满了 原因是nacos日志高达3G,然后将日志文件发给我看了一下之后才发现是gateway整合sentinel使用了默认日志地址导致日志生成地址直接存在与根路径下而且一下存在多…

搜索引擎3Dfindit.com让艰难的工程数据搜索变得简单

3Dfindit让设计师在搜索零件中体验乐趣 Thomas是一位机械工程专业毕业的新人&#xff0c;他迎来了他的第一份工作&#xff0c;兴高采烈地开始着手他的第一个项目&#xff1a;甲方要求设计一个建造在工业区的全新洗车房---龙门式洗车房&#xff1a; 汽车先被喷满泡沫&#xff0c…

安装配置Kafka

一个典型的Kafka集群中包含若干Producer&#xff08;可以是Web前端FET&#xff0c;或者是服务器日志等&#xff09;&#xff0c;若干Broker&#xff08;Kafka支持水平扩展&#xff0c;一般Broker数量越多&#xff0c;集群吞吐率越高&#xff09;&#xff0c;若干ConsumerGroup&…

css相邻元素边框重合问题,解决方案

1、如下图所示&#xff0c;在给元素设置边框后&#xff0c;相邻元素会出现重合的问题 2、解决方案 给每个元素设置margin-top以及margin-left为负的边框 <div style"width: 300px;display: flex;flex-wrap: wrap;margin-top: 50px;"><div style"border…

layoutlmv3训练CDLA数据集

一.LayoutLMv3介绍 LayoutLMv3&#xff08;文档基础模型&#xff09; 自监督预训练技术在文档人工智能方面取得了显着的进步。大多数多模态预训练模型使用掩码语言建模目标来学习文本模态的双向表示&#xff0c;但它们在图像模态的预训练目标上有所不同。这种差异增加了多模态…