文档库 最新最全的文档下载
当前位置:文档库 › 2016最新Android常见面试题

2016最新Android常见面试题

2016最新Android常见面试题
2016最新Android常见面试题

1.横竖屏切换时候activity 的生命周期

1). 不设置Activity 的android:configChanges 时, 切屏会重新调用各个生命周期, 切横屏时会执行一次, 切竖屏时会执行两次.

2). 设置Activity 的Android:configChanges=‖orientation‖ 时, 切屏还是会重新调用各个生命周期, 切横、竖屏时只会执行一次.

3). 设置Activity 的Android:configChanges=‖orientation|keyboardHidden‖ 时, 切屏不会重新调用各个生命周期, 只会执行onConfigurationChanged 方法 .

2.android 中的动画有哪几类,它们的特点和区别是什么?

两种,一种是Tween 动画、还有一种是Frame 动画。Tween 动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化; 另一种Frame 动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。

3. 一条最长的短信息约占多少byte?

中文70( 包括标点) ,英文160 ,160 个字节。

4.handler 机制的原理

andriod 提供了Handler 和Looper 来满足线程间的通信。Handler 先进先出原则。Looper 类用来管理特定线程内对象之间的消息交换(Message Exchange) 。

1)Looper: 一个线程可以产生一个Looper 对象,由它来管理此线程里的Message

Queue( 消息队列) 。

2)Handler: 你可以构造Handler 对象来与Looper 沟通,以便push 新消息到Message Queue 里; 或者接收Looper 从Message Queue 取出) 所送来的消息。

3) Message Queue( 消息队列): 用来存放线程放入的消息。

4) 线程:UI thread 通常就是main thread ,而Android 启动程序时会替它建立一个Message Queue 。

5. 什么是嵌入式实时操作系统, Android 操作系统属于实时操作系统吗?

嵌入式实时操作系统是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。主要用于工业控制、军事设备、航空航天等领域对系统的响应时间有苛刻的要求,这就需要使用实时系统。又可分为软实时和硬实时两种,而android 是基于linux 内核的,因此属于软实时。

6.android 中线程与线程,进程与进程之间如何通信

1)、一个Android 程序开始运行时,会单独启动一个Process 。

默认情况下,所有这个程序中的Activity 或者Service 都会跑在这个Process 。

默认情况下,一个Android 程序也只有一个Process ,但一个Process 下却可以有许多个Thread。

2 )、一个Android 程序开始运行时,就有一个主线程Main Thread 被创建。该线程主要负责UI 界面的显示、更新和控件交互,所以又叫UI Thread 。

一个Android 程序创建之初,一个Process 呈现的是单线程模型—即Main Thread ,所有的任务都在一个线程中运行。所以,Main Thread 所调用的每一个函数,其耗时应该越短越好。而对于比较费时的工作,应该设法交给子线程去做,以避免阻塞主线程(主线程被阻塞,会导致程序假死现象)。

3 )、Android 单线程模型:Android UI 操作并不是线程安全的并且这些操作必须在UI 线程中执行。如果在子线程中直接修改UI ,会导致异常。

7.Android dvm 的进程和Linux 的进程, 应用程序的进程是否为同一个概念

DVM 指dalivk 的虚拟机。每一个Android 应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik 虚拟机实例。而每一个DVM 都是在Linux 中的一个进程,所以说可以认为是同一个概念。

8.sim 卡的EF 文件有何作用

sim 卡的文件系统有自己规范,主要是为了和手机通讯,sim 本身可以有自己的操作系统,EF 就是作存储并和手机通讯用的

9.android 中的动画有哪几类,它们的特点和区别是什么?

两种,一种是Tween 动画、还有一种是Frame 动画。Tween 动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化; 另一种Frame 动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。

1.让Activity 变成一个窗口:Activity 属性设定

讲点轻松的吧, 可能有人希望做出来的应用程序是一个漂浮在手机主界面的东西,那么很简单你只需要设置一下Activity 的主题就可以了在AndroidManifest.xml 中定义Activity 的地方一句话:

Xml 代码

1.android :theme=‖@android:style/Theme.Dialog‖

这就使你的应用程序变成对话框的形式弹出来了,或者

Xml 代码

1.android:theme=‖@android:style/Theme.Translucent‖

就变成半透明的,[ 友情提示-.-] 类似的这种activity 的属性可以在android.R.styleable 类的AndroidManifestActivity 方法中看到,AndroidManifest.xml 中所有元素的属性的介绍都可以参考这个类android.R.styleable

上面说的是属性名称,具体有什么值是在android.R.style 中可以看到,比如这

个‖@android:style/Theme.Dialog‖ 就对应于android.R.style.Theme_Dialog ,(?_‘ 换成?.‘ < —

注意:这个是文章内容不是笑脸) 就可以用在描述文件中了, 找找类定义和描述文件中的对应关系就都明白了。

宅男福利社www.zhainan.hk申博官网https://www.wendangku.net/doc/4b14552665.html,澳门金沙官网https://www.wendangku.net/doc/4b14552665.html,

1.如何将SQLite 数据库 (dictionary.db 文件) 与apk 文件一起发布?

解答:可以将dictionary.db 文件复制到Eclipse Android 工程中的res aw 目录中。

所有在res aw 目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db 文件复制到res aw 目录中

2.如何将打开res aw 目录中的数据库文件?

解答:在Android 中不能直接打开res aw 目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD 卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource 方法获得res aw 目录中资源的InputStream 对象,然后将该InputStream 对象中的数据写入其他的目录中相应文件中。在Android SDK 中可以使用SQLiteDatabase.openOrCreateDatabase 方法来打开任意目录中的SQLite 数据

库文件。

1.在android 中mvc 的具体体现

MVC 是Model,View,Controller 的缩写,从上图可以看出MVC 包含三个部分:

.. 模型(Model )对象:是应用程序的主体部分,所有的业务逻辑都应该写在该

层。

.. 视图(View )对象:是应用程序中负责生成用户界面的部分。也是在整个

MVC 架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。

.. 控制器(Control )对象:是根据用户的输入,控制用户界面数据显示及更新

Model 对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相

关事件,交给M 哦得了处理。

Android 鼓励弱耦合和组件的重用,在Android 中MVC 的具体体现如下

1) 视图层(view ):一般采用xml 文件进行界面的描述,使用的时候可以非常方便的引入,当然,如何你对android 了解的比较的多了话,就一定可以想到在android 中也可以

使用JavaScript+html 等的方式作为view 层,当然这里需要进行Java和JavaScript之间

的通信,幸运的是,android 提供了它们之间非常方便的通信实现。

2) 控制层(controller ):android 的控制层的重任通常落在了众多的acitvity 的肩上,

这句话也就暗含了不要在acitivity 中写代码,要通过activity 交割model 业务逻辑层处理,这样做的另外一个原因是android 中的acitivity 的响应时间是5s ,如果耗时的操作放在

这里,程序就很容易被回收掉。

3) 模型层(model ):对数据库的操作、对网络等的操作都应该在model 里面处理,当

然对业务计算等操作也是必须放在的该层的。

15.Android 系统的架构

android 的系统架构和其操作系统一样,采用了分层的架构。从架构图看,android 分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux 核心层。1. 应用程序

Android 会同一系列核心应用程序包一起发布,该应用程序包包括email 客户端,SMS 短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用Java语言编写的。

2. 应用程序框架

开发人员也可以完全访问核心应用程序所使用的API 框架。该应用程序的架构设计简化了组件的重用; 任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使

用其所发布的功能块( 不过得遵循框架的安全性限制) 。同样,该应用程序重用机制也使用户可以方便的替换程序组件。

隐藏在每个应用后面的是一系列的服务和系统, 其中包括;

* 丰富而又可扩展的视图(Views) ,可以用来构建应用程序,它包括列表(lists) ,网格

(grids),文本框(text boxes) ,按钮(buttons) ,甚至可嵌入的web 浏览器。

* 内容提供器(Content Providers) 使得应用程序可以访问另一个应用程序的数据( 如联系

人数据库) ,或者共享它们自己的数据

* 资源管理器(Resource Manager) 提供非代码资源的访问,如本地字符串,图形,和布局

文件( layout files ) 。

* 通知管理器(Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信

息。

* 活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功

能。

有关更多的细节和怎样从头写一个应用程序,请参考如何编写一个Android 应用程序.

3. 系统运行库

1) 程序库

Android 包含一些C/C++ 库,这些库能被Android 系统中不同的组件使用。它们通过Android应用程序框架为开发者提供服务。以下是一些核心库:

* 系统C 库–一个从BSD 继承来的标准C 系统函数库( libc ) ,它是专门为基于embedded linux 的设备定制的。

* 媒体库–基于PacketVideo OpenCORE; 该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。

* Surface Manager –对显示子系统的管理,并且为多个应用程序提供了2D 和3D 图层的

无缝融合。

* LibWebCore –一个最新的web 浏览器引擎用,支持Android 浏览器和一个可嵌入的

web 视图。

* SGL –底层的2D 图形引擎

* 3D libraries –基于OpenGL ES 1.0 APIs 实现; 该库可以使用硬件3D 加速( 如果可

用) 或者使用高度优化的3D 软加速。

* FreeType –位图(bitmap) 和矢量(vector) 字体显示。

SQLite –一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。

2)Android 运行库

Android 包括了一个核心库,该核心库提供了JAVA 编程语言核心库的大多数功

能。

每一个Android 应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik 虚拟机实例。Dalvik 被设计成一个设备可以同时高效地运行多个虚拟系统。Dalvik 虚拟机执行(.dex) 的Dalvik 可执行文件,该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA 编译器编译,然后通过SDK 中的― dx ‖ 工具转化成.dex 格式由虚拟机执行。

Dalvik 虚拟机依赖于linux 内核的一些功能,比如线程机制和底层内存管理机制。

4.Linux 内核

Android 的核心系统服务依赖于Linux 2.6 内核,如安全性,内存管理,进程管理,网络协议栈和驱动模型。Linux 内核也同时作为硬件和软件栈之间的抽象层。16.Android 常用控件的信息

单选框(RadioButton 与RadioGroup) :

RadioGroup 用于对单选框进行分组,相同组内的单选框只有一个单选框被选中。

事件:setOnCheckedChangeListener() ,处理单选框被选择事件。把

RadioGroup.OnCheckedChangeListener 实例作为参数传入。

多选框(CheckBox):

每个多选框都是独立的,可以通过迭代所有的多选框,然后根据其状态是否被选中在获取其值。

事件:setOnCheckChangeListener() 处理多选框被选择事件。把

CompoundButton.OnCheckedChangeListener 实例作为参数传入

下拉列表框(spring) :

Spinner.getItemAtPosition(Spinner.getSelectedItemPosition()); 获取下拉列表框的值。

事件:setOnItemSelectedListener(), 处理下拉列表框被选择事件把

AdapterView.OnItemSelectedListener 实例作为参数传入;

拖动条(SeekBar) :

SeekBar.getProgress() 获取拖动条当前值

事件:setOnSeekBarChangeListener() ,处理拖动条值变化事件,把

SeekBar.OnSeekBarChangeListener 实例作为参数传入。

菜单(Menu):

重写Activity 的onCreatOptionMenu(Menu menu) 方法,该方法用于创建选项菜单,咋用户按下手机的―Menu‖ 按钮时就会显示创建好的菜单,在onCreatOptionMenu(Menu Menu)

方法内部可以调用Menu.add() 方法实现菜单的添加。

重写Activity 的onMenuItemSelected() 方法,该方法用于处理菜单被选择事件。

进度对话框(ProgressDialog) :

创建并显示一个进度对话框:ProgressDialog.show(ProgressDialogActivity.this,‖ 请稍等‖ ,―数据正在加载中….‖ ,true) ;

设置对话框的风格:setProgressStyle()

ProgressDialog.STYLE_SPINNER 旋转进度条风格( 为默认风格)

ProgressDialog.STYLE_HORIZONTAL 横向进度条风格

1.请介绍下Android 中常用的五种布局

Android 布局是应用界面开发的重要一环,在Android 中,共有五种布局方式,分别是:FrameLayout (框架布局),LinearLayout (线性布局),

AbsoluteLayout (绝对布局),RelativeLayout (相对布局),TableLayout (表格布局)。

1.FrameLayout

这个布局可以看成是墙脚堆东西,有一个四方的矩形的左上角墙脚,我们放了第一

个东西,要再放一个,那就在放在原来放的位置的上面,这样依次的放,会盖住原

来的东西。这个布局比较简单,也只能放一点比较简单的东西。

2.LinearLayout

线性布局,这个东西,从外框上可以理解为一个div ,他首先是一个一个从上往下罗列在屏幕上。每一个LinearLayout 里面又可分为垂直布局

(android:orientation=‖vertical‖ )和水平布局(android:orientation=‖horizontal‖ )。

当垂直布局时,每一行就只有一个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次向右排列。

linearLayout 中有一个重要的属性android:layout_weight=‖1″ ,这个weight 在垂直布局时,代表行距;水平的时候代表列宽;weight 值越大就越大。

3.AbsoluteLayout

绝对布局犹如div 指定了absolute 属性,用X,Y 坐标来指定元素的位置

android:layout_x=‖20px‖ android:layout_y=‖12px‖ 这种布局方式也比较简单,但是在垂直随便切换时,往往会出问题,而且多个元素的时候,计算比较麻烦。

4.RelativeLayout

相对布局可以理解为某一个元素为参照物,来定位的布局方式。主要属性有:

相对于某一个元素

android:layout_below=‖@id/aaa‖ 该元素在id 为aaa 的下面

android:layout_toLeftOf=‖@id/bbb‖ 改元素的左边是bbb

相对于父元素的地方

android:layout_alignParentLeft=‖true‖ 在父元素左对齐

android:layout_alignParentRight=‖true‖ 在父元素右对齐

还可以指定边距等,具体详见API

5.TableLayout

表格布局类似Html 里面的Table 。每一个TableLayout 里面有表格行TableRow ,TableRow 里面可以具体定义每一个元素,设定他的对齐方式android:gravity=‖‖ 。

每一个布局都有自己适合的方式,另外,这五个布局元素可以相互嵌套应用,做出美观的界面。

1.如何启用Service ,如何停用Service

Android 中的服务和windows 中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开

发比较简单,如下:

第一步:继承Service 类

public class SMSService extends Service {

}

第二步:在AndroidManifest.xml 文件中的节点里对服务进行配置:

服务不能自己运行,需要通过调用Context.startService() 或Context.bindService() 方法启动服务。这两个方法都可以启动Service ,但是它们的使用场合有所不同。使用startService() 方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService() 方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有―不求同时生,必须同时死‖的特点。

如果打算采用Context.startService() 方法启动服务,在服务未被创建时,系统会先调用服务的onCreate() 方法,接着调用onStart() 方法。如果调用startService() 方法前服务已经被创建,多次调用startService() 方法并不会导致多次创建服务,但会导致多次调用onStart() 方法。采用startService() 方法启动的服务,只能调用Context.stopService() 方法结束服务,服务结束时会调用onDestroy() 方法。

如果打算采用Context.bindService() 方法启动服务,在服务未被创建时,系统会先调用服务的onCreate() 方法,接着调用onBind() 方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind() 方法,接着调用onDestroy() 方法。如果调用bindService() 方法前服务已经被绑定,多次调用bindService() 方法并不会导致多次创建服

务及绑定( 也就是说onCreate() 和onBind() 方法并不会被多次调用) 。如果调用者希望

与正在绑定的服务解除绑定,可以调用unbindService() 方法,调用该方法也会导致系统调用服务的onUnbind()–>onDestroy() 方法。

服务常用生命周期回调方法如下:

onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService() 或bindService() 方法,服务也只被创建一次。

onDestroy() 该方法在服务被终止时调用。

与采用Context.startService() 方法启动服务有关的生命周期方法

onStart() 只有采用Context.startService() 方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService() 方法尽管不会多次创建服务,但onStart() 方法会被多次调用。

与采用Context.bindService() 方法启动服务有关的生命周期方法

onBind() 只有采用Context.bindService() 方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService() 方法并不会导致该方法被多次调用。

onUnbind() 只有采用Context.bindService() 方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用

采用Context.startService() 方法启动服务的代码如下:

public class HelloActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

……

Button button =(Button) this.findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

Intent intent = new Intent(HelloActivity.this, SMSService.class);

startService(intent);

}});

}

}

采用Context. bindService() 方法启动服务的代码如下:

public class HelloActivity extends Activity {

ServiceConnection conn = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder service) {

}

public void onServiceDisconnected(ComponentName name) {

}

};

@Override

public void onCreate(Bundle savedInstanceState) {

Button button =(Button) this.findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

Intent intent = new Intent(HelloActivity.this, SMSService.class);

bindService(intent, conn, Context.BIND_AUTO_CREATE);

//unbindService(conn);// 解除绑定

}});

}

}

19.ListView 优化

工作原理:

ListView 针对List 中每个item ,要求adapter ― 给我一个视图‖ (getView) 。一个新的视图被返回并显示

如果我们有上亿个项目要显示怎么办?为每个项目创建一个新视图? NO! 这不可能!

实际上Android 为你缓存了视图。

Android 中有个叫做Recycler 的构件,下图是他的工作原理:

如果你有10 亿个项目(item) ,其中只有可见的项目存在内存中,其他的在Recycler 中。

1. ListView 先请求一个type1 视图(getView) 然后请求其他可见的项目。convertView 在getView 中是空(null) 的。

2. 当item1 滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView 再请求一个type1 视图。convertView 此时不是空值了,它的值是item1 。你只需设定新的数据然后返回convertView,不必重新创建一个视图。

20 广播接收者生命周期

一个广播接收者有一个回调方法:void onReceive(Context curContext , Intent broadcastMsg )。当一个广播消息到达接收者是,Android 调用它的onReceive() 方法并传递给它包含消息的Intent对象。广播接收者被认为仅当它执行这个方法时是活跃的。当onReceive() 返回后,它是不活跃的。

有一个活跃的广播接收者的进程是受保护的,不会被杀死。但是系统可以在任何时候杀死仅有不活跃组件的进程,当占用的内存别的进程需要时。

这带来一个问题,当一个广播消息的响应时费时的,因此应该在独立的线程中做这些事,远离用户界面其它组件运行的主线程。如果onReceive() 衍生线程然后返回,整个进程,包括新的线程,被判定为不活跃的(除非进程中的其它应用程序组件是活跃的),将使它处于被杀的危机。解决这个问题的方法是onReceive() 启动一个服务,及时服务做这个工作,因此系统知道进程中有活跃的工作在做。

1.设计模式和IoC( 控制反转)

Android 框架魅力的源泉在于IoC ,在开发Android 的过程中你会时刻感受到

IoC 带来

的巨大方便,就拿Activity 来说,下面的函数是框架调用自动调用的:

protected void onCreate(Bundle savedInstanceState) ;

不是程序编写者主动去调用,反而是用户写的代码被框架调用,这也就反转

了!当然IoC 本身的内涵远远不止这些,但是从这个例子中也可以窥视出IoC

带来的巨大好处。此类的例子在Android 随处可见,例如说数据库的管理类,

例如说Android 中SAX 的Handler 的调用等。有时候,您甚至需要自己编写简

单的IoC 实现,上面展示的多线程现在就是一个说明。

22.Android 中的长度单位详解

现在这里介绍一下dp 和sp 。dp 也就是dip 。这个和sp 基本类似。如果设置表示长度、高度等属性时可以使用dp 或sp 。但如果设置字体,需要使用sp 。dp 是与密度无关,sp 除了与密度无关外,还与scale 无关。如果屏幕密度为160 ,这时dp 和sp 和px 是一样的。1dp=1sp=1px ,但如果使用px 作单位,如果屏幕大小不变(假设还是3.2 寸),而屏幕密度变成了320 。那么原来TextView 的宽度设成160px ,在密度为320 的3.2 寸屏幕里看要比在密度为160 的 3.2 寸屏幕上看短了一半。但如果设置成160dp 或160sp 的话。系统会自动将width 属性值设置成320px 的。也就是160 * 320 / 160 。其中320 / 160 可称为密

度比例因子。也就是说,如果使用dp 和sp ,系统会根据屏幕密度的变化自动

进行转换。

下面看一下其他单位的含义

px :表示屏幕实际的象素。例如,320*480 的屏幕在横向有320 个象素,

在纵向有480 个象素。

in :表示英寸,是屏幕的物理尺寸。每英寸等于2.54 厘米。例如,形容

手机屏幕大小,经常说,3.2 (英)寸、3.5 (英)寸、4 (英)寸就是指这个

单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2 英寸,表示手机

的屏幕(可视区域)对角线长度是 3.2*2.54 = 8.128 厘米。读者可以去量

一量自己的手机屏幕,看和实际的尺寸是否一致。

1. 4 种activity 的启动模式

standard: 标准模式,一调用startActivity() 方法就会产生一个新的实例。

singleTop : 如果已经有一个实例位于Activity 栈的顶部时,就不产生新的实例,而

只是调用Activity中的newInstance() 方法。如果不位于栈顶,会产生一个新的实

例。

singleTask : 会在一个新的task 中产生这个实例,以后每次调用都会使用这个,不

会去产生新的实例了。

singleInstance : 这个跟singleTask 基本上是一样,只有一个区别:在这个模式下的

Activity 实例所处的task 中,只能有这个activity 实例,不能有其他的实例。

2.什么是ANR 如何避免它?

ANR :Application Not Responding ,五秒

在Android 中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。

当出现下列情况时,Android 就会显示ANR 对话框了:

对输入事件( 如按键、触摸屏事件) 的响应超过 5 秒

意向接受器(intentReceiver) 超过10 秒钟仍未执行完毕

Android 应用程序完全运行在一个独立的线程中( 例如main) 。这就意味着,任何

在主线程中运行的,需要消耗大量时间的操作都会引发ANR 。因为此时,你的应

用程序已经没有机会去响应输入事件和意向广播(Intent broadcast) 。

因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate() 和onResume() 等更应如此。潜在的比较耗时的操作,如访问网

络和数据库; 或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成( 或者是使用异步请求,如数据库操作) 。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束—也不需要调用Therad.wait() 或者Thread.sleep() 方法。取而代之

的是,主线程为子线程提供一个句柄(Handler) ,让子线程在即将结束的时候调用它(xing: 可以参看Snake 的例子,这种方法与以前我们所接触的有所不同) 。使用这种方法涉及你

的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过 5 秒钟不被处理而产生的ANR 。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

25.Android Intent 的使用

在一个Android 应用中,主要是由一些组件组成,(Activity,Service,ContentProvider,etc.) 在这些组件之间的通讯中,由Intent 协助完成。

正如网上一些人解析所说,Intent 负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android 则根据此Intent 的描述,负责找到对应的组件,将Intent 传递给调用的组件,并完成组件的调用。Intent 在这里起着实现调用者与被调用者之间的解耦作用。Intent 传递过程中,要找到目标消费者(另一个Activity,IntentReceiver 或Service ),也就是Intent的响应者,有两种方法来匹配:

1 ,显示匹配(Explicit) :

public TestB extents Activity

{

………

};

public class Test extends Activity

{

……

public void switchActivity()

{

Intent i = new Intent(Test.this, TestB.class);

this.startActivity(i);

}

}

代码简洁明了,执行了switchActivity() 函数,就会马上跳转到名为TestB 的Activity 中。

2 ,隐式匹配(Implicit):

隐式匹配,首先要匹配Intent 的几项值:Action, Category, Data/Type,Component

如果填写了Componet 就是上例中的Test.class) 这就形成了显示匹配。所以此部分只讲前几种匹配。匹配规则为最大匹配规则,

1 ,如果你填写了Action ,如果有一个程序的Manifest.xml 中的某一个Activity 的IntentFilter 段中定义了包含了相同的Action 那么这个Intent 就与这个目标Action 匹配,如果这个Filter 段中没有定义Type,Category ,那么这个Activity 就匹配了。但是如果手机中有两个以上的程序匹配,那么就会弹出一个对话可框来提示说明。

Action 的值在Android 中有很多预定义,如果你想直接转到你自己定义的Intent 接收者,你可以在接收者的IntentFilter 中加入一个自定义的Action 值(同时要设定Category 值为‖android.intent.category.DEFAULT‖ ),在你的Intent 中设定该值为Intent 的Action, 就直接能跳转到你自己的Intent 接收者中。因为这个Action 在系统中是唯一的。

2,data/type ,你可以用Uri 来做为data, 比如Uri uri = Uri.parse(https://www.wendangku.net/doc/4b14552665.html, ); Intent i = new Intent(Intent.ACTION_VIEW,uri); 手机的Intent 分发过程中,会根据

https://www.wendangku.net/doc/4b14552665.html,的scheme 判断出数据类型type

手机的Brower 则能匹配它,在Brower 的Manifest.xml 中的IntenFilter 中首先有ACTION_VIEW Action, 也能处理http: 的type ,

3 ,至于分类Category ,一般不要去在Intent 中设置它,如果你写Intent 的接收者,就在Manifest.xml 的Activity 的IntentFilter 中包含android.category.DEFAULT, 这样所有

不设置Category(Intent.addCategory(String c); )的Intent 都会与这个Category 匹配。4,extras (附加信息),是其它所有附加信息的集合。使用extras 可以为组件提供扩展信息,比如,如果要执行― 发送电子邮件‖ 这个动作,可以将电子邮件的标题、正文等保存在extras 里,传给电子邮件发送组件。

相关文档