Android开发基础(一)

Android开发基础(一)
本篇主要是从Android系统架构理解Android开发。
Android

Android系统架构

Android系统的架构采用了分层的架构,共分为五层,从高到低分别是Android应用层(System Apps)、Android应用框架层(Java API Framework)、Android系统运行库层(Native)、硬件抽象层(HAL)和Linux内核层(Linux Kernel);
这种分层架构使得Android系统更加模块化,易于维护和扩展。

一、Android应用层

Android应用层是Android系统架构中的最高层,它直接与用户交互,提供丰富的应用程序供用户使用;
这一层主要包括各种应用程序,如邮件客户端、SMS短消息程序、日历、地图、浏览器、联系人管理程序等,所有这些应用程序都是使用Java语言编写的;
它们通过Android提供的应用程序框架来访问系统服务和资源,实现各种功能;
此外,Android应用层还提供了一些核心应用程序,如主屏幕(HOME)、联系人(Contacts)、电话(Phone)和浏览器(Browser)等;
这些应用程序是Android系统的基本组成部分,用于实现基本的手机功能;
开发人员可以根据需要替换或开发新的应用程序,以扩展Android系统的功能;
在应用框架层,开发人员可以完全访问核心应用程序所使用的API框架。

// 导入所需的API框架  
import android.app.Activity;  
import android.os.Bundle;  
import android.widget.TextView;  
  
public class MyActivity extends Activity {  
    // 定义一个TextView对象,用于显示文本  
    private TextView textView;  
  
    // 在onCreate()方法中初始化TextView对象  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        textView = new TextView(this);  
        setContentView(textView);  
    }  
  
    // 在onResume()方法中更新TextView对象的文本内容  
    @Override  
    protected void onResume() {  
        super.onResume();  
        textView.setText("Hello, World!");  
    }  
}

二、Android应用框架层

Android应用框架层是Android系统中的一层,位于应用层之下,系统运行库层和Linux内核层之上;
这一层是Android应用开发的核心,为开发者在开发应用时提供基础的API框架。这一层集中体现了Android系统的组件设计思想,并且由多个系统服务组成;
Android应用框架层支持包括Activity Manager(活动管理器)、Window Manager(窗口管理器)、Content Providers(内容提供者)、View System(视图系统)、Notification Manager(通知管理器)、Package Manager(包管理器)、Telephony Manager(电话管理器)、Resource Manager(资源管理器)、Location Manager(位置管理器)和XMPPServices(XMPP服务)等在内的多个部分;
其中,Android活动管理器(Activity Manager)用于管理应用程序的生命周期,并提供常用的导航回退功能;
而View System主要用于UI设计,包括List、Grid、Text、Button、Webview等;
此外,Android应用框架层还提供了各种API供开发者使用,例如android.content用于访问和发布各种设备上的数据,android.database则通过内容提供者浏览和操作数据库。

// 获取设备信息
String model = Build.MODEL;  
String manufacturer = Build.MANUFACTURER;
// 访问网络
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);  
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();  
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
// 访问数据库
SQLiteDatabase db = this.getWritableDatabase();  
Cursor cursor = db.rawQuery("SELECT * FROM table_name", null);  
while (cursor.moveToNext()) {  
    int id = cursor.getInt(cursor.getColumnIndex("id"));  
    String name = cursor.getString(cursor.getColumnIndex("name"));  
    // Do something with the data...  
}  
cursor.close();  
db.close();
// 启动活动(Activity)
Intent intent = new Intent(this, AnotherActivity.class);  
startActivity(intent);
// 发送通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")  
    .setContentTitle("Content Title")  
    .setContentText("Content Text")  
    .setSmallIcon(R.drawable.notification_icon);  
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);  
notificationManager.notify(notificationId, builder.build());

三、Android系统运行库层

Android系统的运行库层主要分为两部分:C/C++程序库和Android运行时库;
C/C++程序库能够被Android系统中的不同组件使用,并通过应用程序框架为开发者提供服务;
主要的C/C++程序库包括OpenGL ES(3D绘图函数库)、Libc(从BSD继承来的标准C系统函数库,专门为基于嵌入式Linux的设备定制)、Media Framework(多媒体库,支持多种常用的音频、视频格式录制和回放)、SQLite(轻型的关系型数据库引擎)、SGL(底层的2D图形渲染引擎)、SSL(安全套接层,一种为网络通信提供安全及数据完整性的安全协议)以及FreeType(可移植的字体引擎,提供统一的接口来访问多种字体格式文件);
Android运行时库分为核心库和ART(Android 5.0之前为Dalvik虚拟机,在5.0之后被ART取代);
运行时库提供了核心库和Java语言核心库的大多数功能,开发者可使用Java语言来编写Android应用;
此外,还包含了虚拟机Dalvik(但之后改为了ART运行环境),使每一个Android应用都有自己的进程,并且都有一个自己的Dalvik虚拟机实例;
相较于JAVA的虚拟机,Dalvik是专门为移动设备定制的,针对内存和CPU性能都有了优化。

// 使用数据库
import android.content.ContentValues;  
import android.content.Context;  
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase;  
import android.database.sqlite.SQLiteOpenHelper;  
  
public class MyDatabaseHelper extends SQLiteOpenHelper {  
    private static final String DATABASE_NAME = "mydatabase.db";  
    private static final int DATABASE_VERSION = 1;  
  
    public MyDatabaseHelper(Context context) {  
        super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    }  
  
    @Override  
    public void onCreate(SQLiteDatabase db) {  
        String CREATE_TABLE = "CREATE TABLE mytable (id INTEGER PRIMARY KEY, name TEXT)";  
        db.execSQL(CREATE_TABLE);  
    }  
  
    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
        db.execSQL("DROP TABLE IF EXISTS mytable");  
        onCreate(db);  
    }  
  
    public void addData(String name) {  
        SQLiteDatabase db = this.getWritableDatabase();  
        ContentValues values = new ContentValues();  
        values.put("name", name);  
        db.insert("mytable", null, values);  
        db.close();  
    }  
  
    public Cursor getData() {  
        SQLiteDatabase db = this.getReadableDatabase();  
        Cursor cursor = db.rawQuery("SELECT * FROM mytable", null);  
        return cursor;  
    }  
}
// 画个圆
@Override  
public void onDrawFrame(GL10 gl) {  
    // 清除颜色和深度缓冲  
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  
    // 设置为不进行背面剪裁  
    gl.glDisable(GL10.GL_CULL_FACE);  
  
    // 设置为使用RGBA颜色模式  
    gl.glColor4f(1, 1, 1, 1); // 设置颜色为白色  
    gl.glShadeModel(GL10.GL_FLAT); // 设置着色模型为平面着色  
  
    // 绘制一个填充的圆形,使用正弦和余弦函数来创建圆形路径  
    gl.glBegin(GL10.GL_TRIANGLE_FAN); // 开始绘制一个由三角形的扇形组成的圆  
        for (int i = 0; i <= 90; i++) { // 绘制90个点,形成一个完整的圆  
            float a = i * (2*Math.PI/90); // 角度转弧度  
            float x = 50 * (float)Math.cos(a); // x坐标计算  
            float y = 50 * (float)Math.sin(a); // y坐标计算  
            gl.glVertex2f(x, y); // 添加顶点到路径  
        }  
    gl.glEnd(); // 结束绘制路径  
}

四、硬件抽象层

Android的硬件抽象层(HAL)是一个接口层,它允许应用程序与特定硬件设备进行交互,而无需了解底层硬件的细节;
HAL提供了一种标准化的方式来访问硬件组件,使得应用程序可以在不同的设备和Android版本上保持一致的行为;
HAL的主要目的是将硬件驱动程序与Android系统软件分离,使得硬件厂商可以提供符合标准接口的驱动程序,而无需修改Android系统软件;
这有助于降低硬件和软件之间的耦合度,提高系统的可移植性和可维护性。
在Android中,HAL采用C/C++编写,因为这些语言可以更直接地与硬件交互;
HAL定义了一组标准化的接口,这些接口描述了应用程序可以执行的操作以及它们需要的参数;
硬件厂商需要提供实现这些接口的代码,以便应用程序可以通过HAL与硬件进行通信;
通过HAL,应用程序可以使用标准的API来访问硬件组件,例如相机、传感器、音频编解码器等;
这样,应用程序可以在不同的设备和Android版本上保持一致的行为,而无需针对不同的硬件平台进行定制开发。

// 音频解码
public interface AudioDecoderHal {  
    void open();  
    void setDecodingParams(int sampleRate, int channelConfig, int audioFormat);  
    void startDecoding();  
    void stopDecoding();  
    // 其他相关操作...  
}
// 假设你已经获取到了AudioDecoderHal实例  
AudioDecoderHal decoderHal = ...; // 从适当的地方获取实例  
  
// 打开音频流  
decoderHal.open();  
  
// 设置解码参数  
decoderHal.setDecodingParams(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);  
  
// 开始解码  
decoderHal.startDecoding();  
  
// ... 在此处处理解码后的数据 ...  
  
// 停止解码  
decoderHal.stopDecoding();

五、Linux内核层

Android系统的Linux内核层是Android核心系统的基础,它为Android设备的各种硬件提供底层的驱动,如显示驱动、音频驱动、键盘驱动、电源驱动等;
该层还负责硬件的驱动程序、网络、电源、系统安全以及内存管理等功能;
Android选择采用Linux内核的原因与Linux的特性有关,包括强大的内存管理和进程管理、基于权限的安全模式、支持共享库、经过认证的驱动模式等;
同时,Linux本身就是开源项目,这也符合Android开源的特性;

内存管理

内存管理主要包括物理内存和虚拟内存管理;
在物理内存管理方面,Android主要使用了Low Memory Killer机制,该机制会根据进程的优先级和空闲内存量来决定杀死哪些进程,从而回收内存;
虚拟内存管理方面,Linux内核提供了虚拟内存机制,使得应用程序看到的内存是连续的,而实际的物理内存可能是分散的;
Android在此基础上进行了定制和优化,例如通过Dalvik虚拟机和ART运行环境来管理应用程序的内存分配和回收;
此外,Android系统还引入了多种优化技术来提高内存管理的效率和性能,例如使用内存压缩技术、智能回收技术等;
这些技术有助于减少应用程序的内存占用和提高系统的整体性能。

引用计数

Android的引用计数是一种内存管理技术,用于跟踪和管理对象的生命周期;
通过引用计数,系统可以确定何时释放不再使用的对象,以释放内存;
在Android中,每个对象都有一个与之关联的引用计数器;
当一个对象被创建时,引用计数器初始化为1;
当一个引用指向该对象时,计数器增加1;
当引用被删除或失效时,计数器减少1;
当引用计数器减少到0时,这意味着没有任何引用指向该对象,因此系统可以安全地释放该对象所占用的内存;
Android的引用计数机制有助于防止内存泄漏和确保及时释放不再使用的对象;

public class LeakyActivity extends AppCompatActivity {  
    private static final String TAG = "LeakyActivity";  
    private static final int MAX_POOL_SIZE = 10;  
    private static final Object sPoolMutex = new Object();  
    private static LinkedBlockingQueue<Bitmap> sBitmapPool = new LinkedBlockingQueue<>(MAX_POOL_SIZE);  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_leaky);  
        Button button = findViewById(R.id.leak_button);  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Bitmap bitmap = createBitmap();  
                if (bitmap != null) {  
                    if (sBitmapPool.size() < MAX_POOL_SIZE) {  
                        sBitmapPool.add(bitmap);  
                    } else {  
                        Log.w(TAG, "Bitmap pool is full, not adding more bitmaps.");  
                    }  
                } else {  
                    Log.e(TAG, "Failed to create bitmap.");  
                }  
            }  
        });  
    }  
  
    private Bitmap createBitmap() {  
        // 创建Bitmap的代码...  
        return bitmap;  
    }  
}

以上是一个Android内存泄漏代码示例,由于 sBitmapPool 是静态的,它会在整个应用程序的生命周期内存在,即使 LeakyActivity 已经不再使用;
这意味着即使 LeakyActivity 已经被销毁,但由于池仍然存在并持有对 Bitmap 对象的引用,这些对象将无法被垃圾回收器回收,从而导致内存泄漏;
下面介绍一个循环引用导致内存泄漏的示例。

public class MyActivity extends AppCompatActivity {  
    private MyCustomView customView;  
    private View.OnTouchListener listener = new View.OnTouchListener() {  
        @Override  
        public boolean onTouch(View v, MotionEvent event) {  
            customView.onTouchEvent(event);  
            return true;  
        }  
    };  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_my);  
        customView = findViewById(R.id.custom_view);  
        customView.setOnTouchListener(listener);  
    }  
}  
  
public class MyCustomView extends View {  
    private MyActivity activityRef;  
    // ...其他成员变量和方法...  
  
    public void attachActivity(MyActivity activity) {  
        this.activityRef = activity;  
        // ...执行其他操作...  
    }  
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UML期末复习(带习题,选择题,判断题)(持续更新)

UML期末复习 UML简介UML模型图的构成UML事物UML包含4种事物&#xff1a;构件事物&#xff1a; UML模型的静态部分&#xff0c;描述概念或物理元素行为事物&#xff1a;UML模型图的动态部分&#xff0c;描述跨越空间和时间的行为分组事物&#xff1a; UML模型图的组织部分&#…

某查查请求头参数加密分析(含JS加密算法与Python爬虫源码)

文章目录 1. 写在前面2. 请求分析3. 断点分析4. 扣加密JS5. Python爬虫代码实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff…

Acrel-5000重点用能单位能耗在线监测系统的实际应用分析-安科瑞 蒋静

摘要&#xff1a;根据《重点用能节能办法》&#xff08;国家发展改革委等第七部委2018年15号令&#xff09;、《重点用能单位能耗在线监测系统推广建设工作方案》&#xff08;发改环资[2017]1711号&#xff09;和《关于加速推进重点用能单位能耗在线监测系统建设的通知》&#…

【踩坑】JDK1.8 AudioSystem 无法关闭流的问题

文章目录 一、前言二、开始狼人杀嫌疑人1&#xff1a;嫌疑人2&#xff1a; 三、复盘Jdk8原生bug解决方法和原理解析 一、前言 做了一个基于文字转语言的小接口&#xff0c;想删除本地wav文件来着&#xff0c;结果发现删除不了。 很明显被占用了&#xff0c;还是被Java占用了……

点击出现视频弹框

<VideoPlayer ref"video":size"{ width: 88%, height: 100% }" :videoSrc"currentVideo.url"></VideoPlayer>import VideoPlayer from /components/video-player.vue

MySQL之导入以及导出远程备份v

目录 一.navact数据导入导出 1.1 导入 1.2 导出 二. mysqldump命令导入导出数据 2.1 导入 2.2 导出 三.load data file进行数据导入导出&#xff08;只限于单表&#xff09; 3.1 导入 3.2 导出 四.远程连接 好啦就到这里了哦!!!希望帮到你哦!!! 一.navact数据导入导…

条款21:必须返回对象时,别妄想返回其引用

考虑一个表示有理数的类&#xff0c;其中包含一个计算两个有理数相乘的函数: class Rational { public:Rational(int numerator 0, int denominator 1) :n{ numerator }, d{ denominator }{} private:int n, d; // 分子和分母friend const Rational& operator*(const R…

Win11安装与卸载Oracle 19c数据库

一、官网下载安装包 进入官网&#xff0c;选择产品-Oracle DataBase&#xff0c;点击进入下载界面 官网 二、安装 将下载的压缩包进行解压&#xff0c;解压路径随意即可 1 双击exe文件开始安装 等待出现如下页面 2 选择所示&#xff0c;点击下一步 3 选择桌面类安装 4 创…

2000-2022各省、地级市风险投资(VC)数据

2000-2022各省、地级市风险投资&#xff08;VC&#xff09;数据 1、时间&#xff1a;2000-2022年 2、范围&#xff1a;350个地级市&#xff0c;34省 3、指标&#xff1a;包含投资机构层面的风险投资原始数据&#xff0c;汇总到省市层面的结果数据&#xff0c;具体指标如下&a…

走进shell

Linux系统启动时&#xff0c;会自动创建多个虚拟控制台。虚拟控制台是运行在Linux系统内存中的终端会话。 打开Linux控制台Terminal使用tty命令查看当前使用的虚拟控制台。 注&#xff1a;tty 表示电传打字机(teletypewriter) $ tty /dev/pts/0表示当前使用的是/dev/pts/0 虚拟…

Android 事件分发介绍

文章目录 一、目的二、环境三、相关概念3.1 事件分发 四、详细设计4.1应用布局4.1.1 应用布局结构4.1.2 LayoutInspector 4.2 关键View&方法4.2.1 相关View4.2.2 相关方法4.2.3 View与方法关系 4.3 事件分发概念图4.3.1 事件分发类图4.3.2 事件分发模型图 4.4 Activity组件…

vmlinux, System.map; cmake的find_package(Clang)产生的变量们; geogebra单位切向量(简单例子)

linux4.15.y内核中的函数个数 依赖关系: vmlinux, vmlinux.bin, bzImage cd /bal/linux-stable/ file vmlinux #vmlinux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]b99bbd9dda1ec2751da246d4a7ae4e6fcf7d789b, not str…

渐进增强与优雅降级:提升用户体验的双重策略

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【人工智能】智能电网:未来能源的革命

未来能源的革命 智能电网革命的意义在于将电力行业从传统的集中式发电和集中式输配电模式转变为智能化、分布式、互动式的能源网络。 现在我们从以下方面详细认真的了解一下智能电网&#xff1a; 智能变电站&#xff0c;智能配电网&#xff0c;智能电能表&#xff0c;智能交互…

基于arcgis的遥感深度学习数据集制作

由于很多时候&#xff0c;我们在研究过程中往往需要根据实际情况使用自己的影像数据来提取目标物&#xff0c;如果没有合适的公开数据集的话&#xff0c;为了满足实际需要&#xff0c;我们就需要制作符合自己要求的数据集。 今天我们就根据实际情况来详细讲解如何利用arcgis&am…

CMU15-445-Spring-2023-Project #2 - B+Tree

前置知识&#xff1a;参考上一篇博文 CMU15-445-Spring-2023-Project #2 - 前置知识&#xff08;lec07-010&#xff09; CHECKPOINT #1 Task #1 - BTree Pages 实现三个page class来存储B树的数据。 BTree Page internal page和leaf page继承的基类&#xff0c;只包含两个…

K8S的部署策略,重建更新和滚动更新

Deployment Strategies 部署战略 When it comes time to change the version of software implementing your service, a Kubernetes deployment supports two different rollout strategies: RecreateRollingUpdate 当需要更改实施服务的软件版本时&#xff0c;Kubernetes …

代码随想录刷题题Day29

刷题的第二十九天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day29 任务 ● 01背包问题&#xff0c;你该了解这些&#xff01; ● 01背包问题&#xff0c;你该了解这些&#xff01; 滚动数组 …

WebGL在实验室方向的应用

WebGL在实验室方向的应用涉及到实验过程的可视化、数据分析、模拟等方面。以下是一些WebGL在实验室领域的应用示例&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.分子模型和化学反应模拟&#xff…

element plus el-form双列布局及拓展任意布局

1 场景 一般表单我们直接默认布局&#xff0c;也就是单列布局&#xff0c;突然有个人员信息表单&#xff0c;需要双列布局的需求&#xff0c;简单实现并拓展下 2 思路 直接无脑divflex布局实现 3 代码 <template><el-form ref"formRef" :model"fo…