初级安卓开发需要掌握的知识点主要包括安卓四大组件、Context、Intent、Handler、Fragment、HandlerThread、AsyncTask、IntentService、Binder、AIDL、SharedPreferences、Activity、Window、DecorView以及ViewRoot层级关系、触摸事件分发机制、View绘制流程、自定义View。
1. 环境搭建
- Java:作为Android开发的传统语言,需要掌握面向对象编程、集合框架、异常处理、多线程和网络编程等。
- Kotlin:Google推荐的Android开发语言,提供了更简洁的语法和空安全等特性,需要掌握其基本语法、协程用于异步编程等。
- Android Studio:熟悉Android Studio的项目管理、代码编辑、调试和性能分析工具。
- Gradle:掌握Gradle构建工具,了解其配置和插件使用。
-
JDK:Android开发需要在Java环境下进行,所以需要先安装JDK。
-
Android SDK:包含了开发Android应用所需的所有工具和库。
-
IDE:Android Studio是一个被谷歌推荐的开发环境,也是最常用的一个。
2. Android SDK
- Android四大组件:活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)、内容提供器(Content Provider)
- Activity:包含用户界面的组件,用于和用户交互。理解Activity的生命周期,掌握启动模式和任务栈。Fragment:嵌入在活动中的UI片段,兼顾手机和平板,让界面在平板上更好展示。
- Service:后台服务,不需要和用户交互,但需要长期运行的任务。Android多线程编程 extends Thread、implements Runnable,不允许在子线程进行UI操作,异步消息处理、服务生命周期。服务最佳实践:网络下载。
- BroadcastReceiver:跨进程通信,广播接收器的使用,用于接收系统或应用发出的广播。标准广播(异步)、有序广播(同步)、动态注册(代码)、静态注册(xml)、全局广播、本地广播(解决安全性问题)。广播最佳实践:QQ强制下线。
- ContentProvider:跨程序数据共享(getContentResolver),与运行时权限有关。
• 活动Activity:Android应用程序的核心组成部分。
• 服务Service:在后台运行的组件,不与用户直接交互。
• 内容提供者Content Provider:提供多个应用程序之间共享的数据。
• 广播接收者Broadcast Receiver:能够接收指定的广播消息。
3. UI 界面
- 布局:熟悉各种布局方式,如LinearLayout、RelativeLayout、FrameLayout、PercentFrameLayout等。
- 控件:掌握常见控件如Button、TextView、ImageView、ListView、RecyclerView、MediaPlayer、VideoView、WebView、ViewPager等的使用。
- 数据绑定:使用Data Binding和View Binding简化布局和代码的关联。
- MaterialDesign/DesignSupport:ToolBar、DrawerLayout、NavigationView、FloatingActionButton、SnackBar、CoordinatorLayout、CardView、AppBarLayout、SwipeRefreshLayout、CollapsingToolbarLayout
4. IO 网络和文件
- HTTP请求:HttpURLConnection(官方轻量级)、OkHttp(高效)、Volley(关注图片)、Retrofit(复杂请求)、AsyncHttpClient(复杂请求)。
- XML解析:Pull解析、SAX解析。
- JSON解析:JSONObject(官方、功能简单)、GSON(谷歌、默认推荐)、FastJSON(阿里、高性能)、Jackson。
- 持久化存储:文件存储(openFileOutput)、键值存储(SharedPreferences)、关系存储(SQLiteOpenHelper)、ORM框架(LitePal/Room)
5.Android系统架构
Android系统架构主要分为四部分,包括应用层、应用框架层、系统运行库层和Linux内核层。
- 内核层:Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等。
- 系统运行库层:提供一些特性支持,如数据库支持,OpenGL ES提供3D绘图支持,webkit库提供浏览器内核支持。在这一层还有Android运行时库,它主要提供了一些核心库,允许开发者使用Java语言来编写Android应用。另外,Android运行时库中还包含了Dalvik虚拟机(5.0系统之后改为ART运行环境),它使得每一个Android应用都能运行在独立的进程中,并且拥有一个自己的虚拟机实例。相较于Java虚拟机,Dalvik和ART都是专门为移动设备定制的,它针对手机内存、CPU性能有限等情况做了优化处理。
- 应用框架层这一层主要提供了构建应用程序时可能用到的各种API,Android自带的一些核心应用就是使用这些API完成的,开发者可以使用这些API来构建自己的应用程序。
- 应用层:用户安装的所有应用
• 应用层:用户可视化的应用程序。
• 应用框架层:提供了许多API,为应用程序提供了访问下层的功能。
• 系统运行库层:为开发人员提供了C/C++库,能够使用众多系统服务和库。
• Linux内核层:包含了设备驱动程序,管理底层硬件。
6. Android的视图
• 布局Layouts:用于定义和管理屏幕中的控件。
• 视图View:每一个UI组件,如文本框、按钮、列表项等。
• 文本框TextView:显示文本。
• 按钮Button:用于触发某些操作。
• 列表项ListView:用于显示大量数据,支持滚动。
• 图片视图ImageView:显示位图和其他图像。
7. Android的事件处理
• 视图事件:指根据用户对视图的一些操作所产生的事件。
• 外部事件:指与Android系统和其他应用程序交互时产生的事件。例如电话、短信、电子邮件等。
8. Android的存储管理
- 使用SharedPreference存储数据;它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中,只能在同一个包内使用,不能在不同包之间使用。
- 文件存储数据;文件存储方式是一种叫常用的方法,在Android中读取/写入文件的方法,与java中实现I/O的程序是完全一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件。
- SQlite数据库存储数据;SQlite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。
- 使用ContentProvider存储数据;主要在于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此ContentProvider的各种数据的类型。
- 网络存储数据;同网络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在网络空间中的数据信息。
• SharedPreferences:用于简单的键值存储。
• 文件存储:用于简单的文本或二进制数据存储。
• SQLite数据库:用于丰富的结构化数据存储。
9. Android的网络通信
• HTTP通信:使用HttpURLConnection和Apache HttpClient等类。
• JSON数据:简单的文本格式,用于交换数据。
• XML数据:一种可扩展的标记语言,用于交换数据。
10.项目结构
- gradle.properties这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
- app文件夹,项目的主要主体,也是我们主要的工作目录
- build:编译自动生成的相关中间文件
- libs:第三方jar包
- AndroidTest,安卓测试用例
- java:java代码
- res:资源目录,图片放在drawable目录下,布局放在layout下,图标文件放在mipmap文件夹下,字符串也算资源,放在value下
- AndroidManifest.xml这是整个Android项目的配置文件,你在程序中定义的所有四大组件都需要在这个文件里注册。
- proguard-rules.pro这个文件用于指定项目代码的混淆规则,当代码开发完成后打包成安装包文件,如果不希望代码被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。
layout就是布局,安卓可以在代码中创建视图类,也可以使用xml定义视图layout。
11.Context
Context是安卓应用程序的上下文,用于获取应用程序的资源和相关信息,可以通过getApplicationContext和Activity的this获取。Context包括应用程序的环境信息和资源信息。
12.Intent
Intent是安卓应用程序之间进行通信的载体,可以用于启动活动、启动服务、发送广播等。可以通过putExtra和getExtra传递数据。
intent意为意图,是程序中各组件交互的重要方法,不仅可以指定当前组件要进行的动作,还可以在组件之进行数据的传递。
intent有显示意图和隐式意图之分
显示意图 可以通过名称开启组件
隐式意图 没有明确指定要开启的组件,而是通过指定action。category等舒心信息,系统根据这些信息进行分析,然后寻找目标的Activity。
13.Handler
Handler是安卓中处理消息机制的基础,用于在不同的线程之间传递消息。Handler可以通过post、sendMessage等方法发送消息,通过handleMessage方法处理消息。
14.Fragment
Fragment是安卓中用于构建灵活的UI界面的组件,可以将一个Activity分成多个Fragment,每个Fragment可以有自己的布局和行为。Fragment可以通过FragmentManager进行管理。
15.HandlerThread
HandlerThread是安卓中的一个线程类,用于创建一个带有Looper的线程,可以用于处理消息队列。HandlerThread可以通过start和quit方法启动和停止线程。
16.AsyncTask
AsyncTask是安卓中的一个异步任务类,用于在后台执行一些耗时的操作,可以在后台线程中更新UI。AsyncTask包括onPreExecute、doInBackground、onProgressUpdate、onPostExecute等方法。
17.IntentService
IntentService是安卓中的一个服务类,用于处理一些异步任务,可以在后台线程中执行。IntentService可以通过onHandleIntent方法处理任务。
18.Binder
Binder是安卓中的一个IPC机制,用于在不同的进程之间进行通信。Binder可以通过IBinder接口进行通信。
19.AIDL
AIDL是安卓中的一个IPC机制,用于跨进程通信。AIDL可以通过接口文件和Stub类进行实现。
20.SharedPreferences
SharedPreferences是安卓中的一个轻量级存储类,用于存储一些简单的数据,如用户名、密码等。SharedPreferences可以通过getSharedPreferences方法获取。
21.Window、DecorView以及ViewRoot层级关系
Window、DecorView和ViewRoot是安卓中的三个重要概念。Window是安卓应用程序界面的最顶层容器,DecorView是Window中的一个ViewGroup,包括标题栏、内容区域和状态栏,ViewRoot是DecorView的父容器。
22.触摸事件分发机制
触摸事件分发机制是安卓中的一个重要机制,用于处理用户的触摸事件。触摸事件分发机制包括事件分发、事件拦截和事件处理。
23.View绘制流程
View的绘制流程是安卓中的一个重要概念,用于实现自定义View。View的绘制流程包括测量、布局和绘制。
24.自定义View
自定义View是安卓中的一个重要技术,可以实现灵活的UI界面。自定义View需要了解View的测量、布局和绘制流程,以及Canvas、Paint等相关知识。
25.Android中五大布局
1.LinearLayout线性布局
线性布局在实际开发中很常用,它主要以水平和垂直的方式显示界面中的控件。线性布局中有一个非常重要的属性orientation用于控制控件排列的方向,vertical表示垂直显示,horizonal表示水平显示。
2.RelativeLayout相对布局
是通过相对定位的方式指定控件位置,在设计的时候遵循控件之间的依赖关系,后放入的控件的位置依赖于先放入的控件的位置。
3.FrameLayout帧布局
为每个加入其中的控件创建一个白区域,帧布局大小有内部最大控件决定
4.AbsoluteLayout绝对布局
通过指定X,Y坐标的控制每个控件的位置
5.TableLayout表格布局
通过行和列将界面划分为多个单元,每个单元可以添加控件
26.Activity启动模式
介绍Android启动模式之前,先介绍两个概念task和taskAffinity
- task:翻译过来就是“任务”,是一组相互关联的activity集合,可以理解为Activity是在task里面活动的。task存在于一个被称为back stack的数据结构中,也就是说,task是以栈的形式去管理activity的,所以也可以叫做“任务栈”。
- taskAffinity:官方文档翻译是:“The task that the activity has a affinity for.”,可以翻译为activity相关或者亲和任务,这个参数标识了一个Activity所需要的任务栈的名字。默认情况下,所有Activity所需要的任务栈的名字为应用的包名。taskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用。
4种启动模式
- standard:标准模式,也是系统默认的启动模式。假如activity A启动了activity B,activity B则会运行在activity A所在的任务栈中。而且每次启动一个Activity,都会重新创建新的实例,不管这个实例在任务中是否已经存在。非Activity类型的context(如ApplicationContext)启动standard模式的Activity时会报错。非Activity类型的context并没有所谓的任务栈,由于上面第1点的原因所以系统会报错。此解决办法就是待启动acti指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候系统就会为它创建一个新的任务栈。这个时候待启动Activity其实是以singleTask模式启动的。
- singleTop:栈顶复用模式。假如activity A启动了activity B,就会判断A所在的任务栈栈顶是否是B实例。如果是,则不创建新的activity B实例而是直接引用这个栈顶实例,同时onNewIntent方法会被调用,通过该方法的参数可以取得当前请求的信息;如果不是,则创建新的activity B实例。
- singleTask:栈内复用模式。在第一次启动这个Activity时,系统便会创建一个新的任务,并且初始化Activity的实例,放在心任务的底部。不过需要满足一定条件的。那就是需要设置taskAffinity属性。前面也说过了,taskAffinity属性是和singleTask模式搭配使用的。
[图片上传失败...(image-4509a9-1593940979666)] - singleInstance:单实例模式。这个时singleTask模式的加强版,它除了具有singleTask模式的所有特性外,它还有一点独特的特性,那就是此模式的Activity只能单独地位于一个任务栈,不与其他Activity共存于同一个任务栈。
27.广播注册
首先写一个类要继承BroadCastReceiver
第一种:在清单文件中声明,添加
第二种:使用代码进行注册如:
两种注册类型的区别是:
- 第一种是常驻型广播,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
- 第二种不是常驻型广播,也就是说广播跟随程序的生命周期。
28.Android中的ANR
ANR的全称application not responding responding 应用程序未响应。
- 在android中Activity的最长执行事时间为5秒。
- broadcastreceiver的最长执行时间则是10秒。
- Service的最长执行时间是20秒。
超过执行时间就会产生ANR。注意:ANR是系统抛出的异常,程序是捕捉不了这个异常的。
解决方法:
- 运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和OnResue())里尽可能少的去做创建操作。(可以采用重新开启子线程的方式,然后使用hander+message的方式去做一些操作,比如更新主线程中的UI等)。
- 应用程序应该避免在broadcastreceiver里面做耗时的操作或者计算。但不再是在子线程里做这些任务(因为broadcastreceiver的生命周期短)替代的是,如果响应intent广播需要执行一个耗时的动作的话,应用程序应该启动一个Service。
29.ListView优化
- convertView重用,利用好convertView来重用View,切勿每次getView()都新建。ListView的核心原理就是重用View,如果重用View不改变宽高,重用View就可以减少重新分配缓存造成的内存频繁分配/回收。
- ViewHolder优化,使用ViewHolder的原因是findViewById方法耗时较大,如果控件个数过多,会严重影响性能,而使用ViewHolder主要是为了可以省去这个时间。通过setTag,getTag直接获取View。
- 减少ItemView的布局层次,这是所有layout都必须遵循的,布局层级过深会直接导致View的测量和绘制浪费大量的时间。
- adapter中的getView方法尽量少使用逻辑。
- 图片加载采用三级缓存,避免每次都要重新加载。
- 尝试开启硬件加速来使ListView的滑动更加流畅。
- 使用RecycleView代替。
当 convertView 为空时,用 setTag()方法为每个 View 绑定一个存放控件的 ViewHolder 对象。当convertView 不为空, 重复利用已经创建的 view 的时候, 使用 getTag()方法获取绑定的 ViewHolder对象,这样就避免了 findViewById 对控件的层层查询,而是快速定位到控件。 复用 ConvertView,使用历史的 view,提升效率 200%
自定义静态类 ViewHolder,减少 findViewById 的次数。提升效率 50%
异步加载数据,分页加载数据。
使用 WeakRefrence 引用 ImageView 对象
30.Thread和Runnable的区别
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比。
继承Thread类有如下好处:
- 避免点继承的局限,一个类可以继承多个接口。
- 适合于资源的共享
在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。
31.Android中activity,context,application有什么不同
Content与application都继承与contextWrapper,contextWrapper继承于Context类。
Context:表示当前上下文对象,保存的是上下文中的参数和变量,它可以让更加方便访问到一些资源。
Context通常与activity的生命周期是一样的,application表示整个应用程序的对象。
对于一些生命周期较长的,不要使用context,可以使用application。
在activity中,尽量使用静态内部类,不要使用内部类。内部里作为外部类的成员存在,不是独立于activity,如果内存中还有内存继续引用到context,activity如果被销毁,context还不会结束。
Context区别
- Activity和Service以及Application的Context是不一样的,Activity继承自ContextThemeWraper.其他的继承自ContextWrapper
- 每一个Activity和Service以及Application的Context都是一个新的ContextImpl对象
- getApplication()用来获取Application实例的,但是这个方法只有在Activity和Service中才能调用的到。那么也许在绝大多数情况下我们都是在Activity或者Service中使用Application的,但是如果在一些其它的场景,比如BroadcastReceiver中也想获得Application的实例,这时就可以借助getApplicationContext()方法,getApplicationContext()比getApplication()方法的作用域会更广一些,任何一个Context的实例,只要调用getApplicationContext()方法都可以拿到我们的Application对象。
- Activity在创建的时候会new一个ContextImpl对象并在attach方法中关联它,Application和Service也差不多。ContextWrapper的方法内部都是转调ContextImpl的方法
- 创建对话框传入Application的Context是不可以的
- 尽管Application、Activity、Service都有自己的ContextImpl,并且每个ContextImpl都有自己的mResources成员,但是由于它们的mResources成员都来自于唯一的ResourcesManager实例,所以它们看似不同的mResources其实都指向的是同一块内存
- Context的数量等于Activity的个数 + Service的个数 + 1,这个1为Application
32.Serializable 和 Parcelable 的区别?
如果存储在内存中,推荐使用parcelable,使用serialiable在序列化的时候会产生大量的临时变量,会引起频繁的GC
如果存储在硬盘上,推荐使用Serializable,虽然serializable效率较低
Serializable的实现:只需要实现Serializable接口,就会自动生成一个序列化id
Parcelable的实现:需要实现Parcelable接口,还需要Parcelable.CREATER变量
33.uses-permission和permission的区别
就是<uses-permission>是官方定义的权限,是调用别人的东西的时候自己需要声明的权限,<permission>是自己定义的权限,就是别人调用这个程序时需要用<uses-permission>来声明。
在一般情况下实际上不需要为自己的应用程序声明某个权限,除非你提供了供其他应用程序调用的代码或者数据。这个时候你才需要使用<permission>这个标签,很显然这个标签可以让我们声明自己程序的权限。
34.Fragment 在你们项目中的使用
Fragment 是 android3.0 以后引入的的概念,做局部内容更新更方便,原来为了到达这一点要把多个布局放到一个 activity 里面,现在可以用多 Fragment 来代替,只有在需要的时候才加载Fragment,提高性能。
Fragment 的好处:
- Fragment 可以使你能够将 activity 分离成多个可重用的组件,每个都有它自己的生命周期和UI。
- Fragment 可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
- Fragment 是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。
- Fragment 提供一个新的方式让你在不同的安卓设备上统一你的 UI。
- Fragment 解决 Activity 间的切换不流畅,轻量切换。
- Fragment 替代 TabActivity 做导航,性能更好。
- Fragment 在 4.2.版本中新增嵌套 fragment 使用方法,能够生成更好的界面效果。
35.Android 线程间通信有哪几种方式
- 共享内存(变量);
- 文件,数据库;
- Handler;
- Java 里的 wait(),notify(),notifyAll();
36.Framework 工作方式及原理,Activity 是如何生成一个 view 的,机制是什么?
所有的框架都是基于反射 和 配置文件(manifest)的。
普通的情况:
Activity 创建一个 view 是通过 ondraw 画出来的, 画这个 view 之前呢,还会调用 onmeasure方法来计算显示的大小.
特殊情况:
Surfaceview 是直接操作硬件的,因为 或者视频播放对帧数有要求,onDraw 效率太低,不够使,Surfaceview 直接把数据写到显存。
37.Android中touch事件的传递机制是怎样的?
- Touch事件传递的相关API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
- Touch事件相关的类有View、ViewGroup、Activity
- Touch事件会被封装成MotionEvent对象,该对象封装了手势按下、移动、松开等动作
- Touch事件通常从Activity#dispatchTouchEvent发出,只要没有被消费,会一直往下传递,到最底层的View。
- 如果Touch事件传递到的每个View都不消费事件,那么Touch事件会反向向上传递,最终交由Activity#onTouchEvent处理.
- onInterceptTouchEvent为ViewGroup特有,可以拦截事件.
- Down事件到来时,如果一个View没有消费该事件,那么后续的MOVE/UP事件都不会再给它
38.描述下Handler 机制
- Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。
- Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
- Message Queue(消息队列):用来存放线程放入的消息。
- 线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。
Hander持有对UI主线程消息队列MessageQueue和消息循环Looper的引用,子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。
39.自定义view的基本流程
- 自定义View的属性 编写attr.xml文件
- 在layout布局文件中引用,同时引用命名空间
- 在View的构造方法中获得我们自定义的属性 ,在自定义控件中进行读取(构造方法拿到attr.xml文件值)
- 重写onMesure
- 重写onDraw
-
onMeasure()
-
onLayout()
-
onDraw()。
40.事件分发中的 onTouch 和 onTouchEvent 有什么区别,又该如何使用?
这两个方法都是在 View 的 dispatchTouchEvent 中调用的,onTouch 优先于 onTouchEvent执行。如果在 onTouch 方法中通过返回 true 将事件消费掉,onTouchEvent 将不会再执行。
另外需要注意的是,onTouch 能够得到执行需要两个前提条件,第一 OnTouchListener 的值不能为空,第二当前点击的控件必须是 enable 的。因此如果你有一个控件是非 enable 的,那么给它注册 onTouch 事件将永远得不到执行。对于这一类控件,如果我们想要监听它的 touch 事件,就必须通过在该控件中重写 onTouchEvent 方法来实现。
41.一般在开发项目中都使用什么设计模式?如何来重构,优化代码?
较为常用的就是单例设计模式,工厂设计模式以及观察者设计模式,
一般需要保证对象在内存中的唯一性时就是用单例模式,例如对数据库操作的 SqliteOpenHelper 的对象。
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
42.andorid 应用第二次登录实现自动登录
前置条件是所有用户相关接口都走 https,非用户相关列表类数据走 http。
- 第一次登陆 getUserInfo 里带有一个长效 token,该长效 token 用来判断用户是否登陆和换取短 token
- 把长效 token 保存到 SharedPreferences
- 接口请求用长效 token 换取短token,短 token 服务端可以根据你的接口最后一次请求作为标示,超时时间为一天。
- 所有接口都用短效 token
- 如果返回短效 token 失效,执行第3步,再直接当前接口
- 如果长效 token 失效(用户换设备或超过一月),提示用户登录。
43.怎样对 android 进行优化?
- 对 listview 的优化。
- 对图片的优化。
- 对内存的优化。
- 具体一些措施
- 尽量不要使用过多的静态类 static
- 数据库使用完成后要记得关闭 cursor
- 广播使用完之后要注销
44.wait()和sleep()的区别
sleep()方法是线程类(Thread)的静态方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复(线程回到就绪(ready)状态),因为调用sleep 不会释放对象锁。wait()是Object 类的方法,对此对象调用wait()方法导致本线程放弃对象锁(线程暂停执行),进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入就绪状态。
45.logcat的使用
Android使用Android.util.Log类的静态方法实现输出程序信息。Logcat输出日志内容分为6个级别,分别是Verbose(V)显示全部信息、debug(D)显示调试信息、info(I)显示一般信息、warning(W)显示警告信息、error(E)显示错误信息、Assert(A)没有对应的方法。
46.清单文件
清单文件AndroidMainifest.xml是整个项目配置文件,程序中定义的四大组件(Acticity、brindcastRecever、Service、contentProvider)都要在这个文件中配置,同时在这个文件中注册APP的各项权限。
47.Activity的四种启动模式
1.standard模式
每启动一个Activity就在栈顶创建一个新的实例
2.singleTop模式
判断要启动的Activity实例是否存在于栈顶,如果位于栈顶就直接复用,否则创建新的实例
3.singleTask模式
每次启动Activity时,系统首先检查栈中是否存在当前的Activity实例,如果存在就直接使用,并且把当前的Activity之上的所有Activity出栈,否则重新创建一个新的实例。
4.singleInstance模式
回启动一个新的Activity来管理Activity实例