Android开发你必须了解的几个原理

公众号:码农乐园 等级 795 1 0

随着互联网的迅速发展,Android技术也是发生很大的变化,要求也是越来高了,在11,12年只要会基本的Android组件,会listview,分享就感觉很牛了,智能手机的发展,及用户普通追求高效率,用户体验的提升,要求开发人员必须会懂实现原理及优化APP程序;不管是面试他人还是被面试目前都经常问到原理性的问题,handler实现原理,activity启动原理,进程通信原理,多线程等等,接下来我聊聊面试中经常遇到的原理问题;

一,ContentProvider进程间如何共享数据的,数据存在哪里?

1,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数据暴露的。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URL来表示外界需要访问的“数据库”。

2,ContentProvider提供了一种多应用间数据共享的方式。ContentProvider是个实现了一组用于提供其他应用程序存取数据的标准方法的类。应用程序可以在ContentProvider中执行如下操作:查询数据、修改数据、添加数据、删除数据。

3,标准的ContentProvider:Android提供了一些已经在系统中实现的标准,比如联系人信息,图片库等等,可以用这些ContentProvider来访问设备上存储的联系人信息、图片等等。

4,在ContentProvider中使用的查询字符串有别于标准的SQL查询,很多诸如select、add、delete、modify等操作都使用一种特殊的URL进行,这种URL由3部分组成,“content://”,代表数据的路径和一个可选的表示数据的ID。

content://media/internal/images 这个URL将返回设备上存储的所有图片

content://contacts/people/ 这个URL将返回设备上的所有联系人信息

content://contacts/people/9 这个URL返回单个结果(联系人信息中ID为9的联系人记录)

5,如果想要存储字节型数据,比如位图文件等,那保存该数据的数据列其实是一个表示实际保存保存文件的URL字符串,客户端通过它来读取对应的文件数据,处理这种数据类型的ContentProvider需要实现一个名为_data的字段,_data字段列出了该文件在Android文件系统上的精确路径。这个字段不仅是供客户端使用,而且也可以供ContentResolver使用。客户端可以调用ContentResolver.openOutputStream()方法来处理该URL指向的文件资源,如果是ContentResolver本身的话,由于其持有的权限比客户端要高,所以它能直接访问该数据文件。

ContentProvider使用Android文件系统或者SQLite数据库来保持数据,但是也可以以任何方式来存储。本例用SQLite数据库来保持数据。

二,Android中的handler大家都熟悉,handler是原理及looper.loop在主线程轮询为什么不会导致主线程阻塞?

1、handler封装消息的发送(主要包括消息发送给谁)

2、Looper——消息封装的载体。(1)内部包含一个MessageQueue,所有的Handler发送的消息都走向这个消息队列;(2)Looper.Looper方法,就是一个死循环,不断地从MessageQueue取消息,如果有消息就处理消息,没有消息就阻塞。

3、MessageQueue,一个消息队列,添加消息,处理消息

4、handler内部与Looper关联,handler->Looper->MessageQueue,handler发送消息就是向MessageQueue队列发送消息。

activityThread并不是一个Thread,只是一个final类,主线一般是从这个类的main方法开始,在activityThread中可以看到有Looper,接着可以找找对应的handler,继承了handler 在handleMessage的部分看出 Activity 的生命周期都有对应的 case 条件了

public void handleMessage(Message msg) {

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

switch (msg.what) {

case LAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");

final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(

r.activityInfo.applicationInfo, r.compatInfo);

handleLaunchActivity(r, null);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

case RELAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");

ActivityClientRecord r = (ActivityClientRecord)msg.obj;

handleRelaunchActivity(r);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

case PAUSE_ACTIVITY:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");

handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,

(msg.arg1&2) != 0);

maybeSnapshot();

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case PAUSE_ACTIVITY_FINISHING:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");

handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,

(msg.arg1&1) != 0);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case STOP_ACTIVITY_SHOW:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");

handleStopActivity((IBinder)msg.obj, true, msg.arg2);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case STOP_ACTIVITY_HIDE:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");

handleStopActivity((IBinder)msg.obj, false, msg.arg2);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case SHOW_WINDOW:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");

handleWindowVisibility((IBinder)msg.obj, true);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case HIDE_WINDOW:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");

handleWindowVisibility((IBinder)msg.obj, false);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

case RESUME_ACTIVITY:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");

handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

ActivityThread 有个 getHandler 方法,得到这个 handler 就可以发送消息,然后 loop 里就分发消息,然后就发给 handler, 然后就执行到 H(Handler )里的对应代码。所以这些代码就不会卡死~,有消息过来就能执行。

三、Activity启动过程

一切从main()方法开始

Android中,一个应用程序的开始可以说就是从ActivityThread.java中的main()方法开始的。都是学过Java的人,想必也都知道Java的程序入口就是main()方法。从这点而言,我们可以把它想成是一个Java程序(注意,不是说Android是个Java程序哦)去理解。

main()方法中主要做的事情有:

初始化主线程的Looper、主Handler。并使主线程进入等待接收Message消息的无限

public static void main(String[] args){

...

Looper.prepareMainLooper();

//初始化Looper

...

ActivityThread thread = new ActivityThread();

//实例化一个ActivityThread

thread.attach(false);

//这个方法最后就是为了发送出创建Application的消息

...

Looper.loop();

//主线程进入无限循环状态,等待接收消息

} Android开发你必须了解的几个原理

收藏
评论区

相关推荐

Android Handler消息机制源码解析
好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础。下面我们分析一下Handler的源码实现。 Handler消息机制有4个类合作完成,分别是Handler,MessageQueue,Looper,Message Handler : 获取消息,发送消息,以及处理消息的类 Mes
Android Activity生命周期,启动模式,启动过程详解
前言 接触过Android开发的同学都知道Activity,Activity作为Android四大组件之一,使用频率高。简单来说Activity提供了一个显示界面,让用户进行各种操作,本文主要分为以下三个部分:Activity的生命周期,启动模式,以及Activity的工作过程。文中大部分篇幅来自《Android开发艺术探索》一书,尽管想多以流程或图
Android开发你必须了解的几个原理
随着互联网的迅速发展,Android技术也是发生很大的变化,要求也是越来高了,在11,12年只要会基本的Android组件,会listview,分享就感觉很牛了,智能手机的发展,及用户普通追求高效率,用户体验的提升,要求开发人员必须会懂实现原理及优化APP程序;不管是面试他人还是被面试目前都经常问到原理性的问题,handler实现原理,activity启动原
Android Fragment生命周期
Fragment 是在 Android 3.0 中引入,用于解决不同屏幕分辨率的设备上 UI 显示、交互的问题。Fragment 有自己的布局,有自己的生命周期,有自己的事件响应。 但 Fragment 又是依赖于 Activity 存在的,你可以把多个 Fragment 嵌入到一个 Activity 中或者多个 Activity 重用一个 Fragmen
Android深入四大组件(一)应用程序启动过程(前篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「后厂技术官」 前言在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。<!more 1
Android深入四大组件(二)Service的启动过程
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读和这两篇文章。<!more 1.ContextImpl到Activi
Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言在几个月前我写了和这两篇文章,它们都是基于Android 7.0,当我开始阅读Android 8.0源码时发现应用程序(根Activity)启动过程照Android 7.0有了一些变化,因此又写下了本篇文章,本篇文章照此前的文章不仅
Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)
Android框架层 Android深入四大组件categories: Android框架层本文首发于微信公众号「刘望舒」 前言在几个月前我写了和这两篇文章,它们都是基于Android 7.0,当我开始阅读Android 8.0源码时发现应用程序(根Activity)启动过程照Android 7.0有了一些变化,因此又写下了本篇文章,本篇文章照此前的文章不仅
全靠这份Android知识点PDF大全,月薪30K
第一阶段:Android 基础知识回顾: 回顾Android 开发编程,深入理解Android系统原理和层次结构,深入分析Handler源码和原理; 回顾Java,C/C++,Kotlin、dart 在Android开发中必用的语言,熟悉一下几种语言混淆后的特性; 回顾Android IPC和JNI的底层原理和热更新技术回顾Native开发要点,使用C++结
Activity跳转通过EventBus传值问题
根据阿里发布的Android开发规范:下载地址:[https://102.alibaba.com/downloadFile.do?file=1520478361732/Android\_v9.pdf](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2F102.alibaba.com%2Fdow
Android 插件化原理解析——Activity生命周期管理
在Java平台要做到动态运行模块、热插拔可以使用`ClassLoader`技术进行动态类加载,比如广泛使用的`OSGi`技术。在Android上当然也可以使用动态加载技术,但是仅仅把类加载进来就足够了吗?`Activity`,`Service`等组件是有生命周期的,它们统一由系统服务`AMS`管理;使用`ClassLoader`可以从插件中创建Activit
Android 面试常问七道题
1Android的四大组件以及作用 **Activity**:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑。 **service**:后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的动作,
Android面试收集录18 Android Context详解
Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用JAVA语言,Activity本质上也是一个对象,那上面的写法有什么问题呢?估计很多人说不清道不明。Android程序不像Java程序一样,随便创建一个类,写个main(
Rxjava和EventBus对比
总的来说,EventBus是一款针对Android优化的发布/订阅事件总线,主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。而Rxjava则是一种基于异步数据流的处理方案。如果一个订阅者需要注册多个事件的时候,Rxjava需要一个个单独的注册,而EventBus则可以实现一