`

Android面试题目及其答案

阅读更多



1、  Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念?

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

2、    sim卡的EF 文件有何作用?

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

3、    嵌入式操作系统内存管理有哪几种, 各有何特性?

页式,段式,段页,用到了MMU,虚拟空间等技术

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

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

5、    一条最长的短信息约占多少byte?

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

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

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

7、    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。

8、    说说mvc模式的原理,它在android中的运用

MVC(Model_view_contraller)”模型_视图_控制器”。 MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View,或者同时改变两者。只要 Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。

9、    Activity的生命周期?

你自己写的Activity会按需要 重载这些方法,onCreate是免不了的,在一个Activity正常启动的过程中,他们被调用的顺序是 onCreate -> onStart -> onResume, 在Activity被干掉的时候顺序是onPause -> onStop -> onDestroy ,这样就是一个完整的生命周期,但是有人问了 ,程序正运行着呢来电话了,这个程序咋办?中止了呗,如果中止的时候新出的一个Activity是全屏的那么:onPause->onStop ,恢复的时候onStart->onResume ,如果打断 这个应用程序的是一个Theme为Translucent 或者Dialog 的Activity那么只是onPause ,恢复 的时候onResume 。 

  详细介绍一下这几个方法中系统在做什么以及我们应该做什么: 

  onCreate: 在这里创建界面 ,做一些数据 的初始化工作 

  onStart: 到这一步变成用户可见不可交互 的 

  onResume: 变成和用户可交互 的,(在activity 栈系统通过栈的方式管理这些个 

  Activity的最上面,运行完弹出栈,则回到上一个Activity) 

  onPause: 到这一步是可见但不可交互 的,系统会停止动画 等消耗CPU 的事情 

  从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候 

  你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在 

  onResume里读出来,注意:这个方法里做的事情时间要短,因为下一 

  个activity不会等到这个方法完成才启动 

  onstop: 变得不可见 ,被下一个activity覆盖了 

  onDestroy: 这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方 

  法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判 

  断它,如果你有一个Progress Dialog在线程中转动,请在onDestroy里 

  把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛 

  异常的。 

  onPause,onstop, onDestroy,三种状态 下 activity都有可能被系统干掉 

  为了保证程序的正确性,你要在onPause()里写上持久层操作的代码,将用户编辑的内容都保存到存储介质上(一般都是数据库 )。实际工作中因为生命周期的变化而带来的问题也很多,比如你的应用程序起了新的线程在跑,这时候中断了,你还要去维护那个线程,是暂停还是杀掉还是数据回滚,是吧?因为Activity可能被杀掉,所以线程中使用的变量和一些界面元素就千万要注意了,一般我都是采用Android的消息机制 [Handler,Message]来处理多线程和界面交互的问题。

10、 让Activity变成一个窗口:Activity属性设定

在AndroidManifest.xml 中定义 Activity的 地方加一句话:

android:theme="@android:style/Theme.Dialog"(对话框)或者

android:theme="@android:style/Theme.Translucent" (半透明)

11、 你后台的Activity被系统回收怎么办?

当你的程序中某一个Activity A 在运行时中,主动或被动地运行另一个新的Activity B 

  这个时候A会执行 

  Java代码 

  1. public 

  2. void onSaveInstanceState(Bundle outState) { 

  3. super.onSaveInstanceState(outState); 

  4. outState.putLong("id", 1234567890); 

  5. } 

  public 

  void onSaveInstanceState(Bundle outState) { 

  super.onSaveInstanceState(outState); 

  outState.putLong("id", 1234567890); 

  } 

  B 完成以后又会来找A, 这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回 

  收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数 

  savedInstanceState,没被收回的就还是onResume就好了。 

  savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。 

  Java代码 

  1. if(savedInstanceState != null){ 

  2. long id = savedInstanceState.getLong("id"); 

  3. } 

  if(savedInstanceState != null){ 

  long id = savedInstanceState.getLong("id"); 

  } 

  就像官方的Notepad教程 里的情况,你正在编辑某一个note,突然被中断,那么就把这个note的id记住,再起来的时候就可以根据这个id去把那个note取出来,程序就完整一些。这也是看你的应用需不需要保存什么,比如你的界面就是读取一个列表,那就不需要特殊记住什么,哦, 没准你需要记住滚动条的位置...

12、 调用与被调用:我们的通信使者Intent

要说Intent了,Intent就是这个这个意图 ,应用程序间Intent进行交流,打个电话啦,来个 

  电话啦都会发Intent, 这个是Android架构的松耦合的精髓部分,大大提高了组件的复用性,比如你要在你的应用程序中点击按钮,给某人打电话,很简单啊,看下代码先: 

  Java代码 

  1. Intent intent = new Intent(); 

  2. intent.setAction(Intent.ACTION_CALL); 

  3. intent.setData(Uri.parse("tel:" + number)); 

4. startActivity(intent); 

  Intent intent = new Intent(); 

  intent.setAction(Intent.ACTION_CALL); 

  intent.setData(Uri.parse("tel:" + number)); 

  startActivity(intent); 

  扔出这样一个意图,系统看到了你的意图就唤醒了电话拨号程序,打出来电话。什么读联系人,发短信啊,邮件啊,统统只需要扔出intent就好了,这个部分设计 地确实很好啊。 

  那Intent通过什么来告诉系统需要谁来接受他呢? 

  通常使用Intent有两种方法,第一种是直接说明需要哪一个类来接收代码如下: 

  Java代码 

  1. Intent intent = new Intent(this, MyActivity.class); 

  2. intent.getExtras().putString("id", "1"); 

  3. tartActivity(intent); 

  Intent intent = new Intent(this, MyActivity.class); 

  intent.getExtras().putString("id", "1"); 

  tartActivity(intent); 

  第一种方式很明显,直接指定了MyActivity为接受者,并且传了一些数据给MyActivity,在MyActivity里可以用getIntent()来的到这个intent和数据。 

  第二种就需要先看一下AndroidMenifest中的intentfilter的配置了 

  Xml代码 

  < intent-filter> 

  < action android:name="android.intent.action.VIEW" 

  /> 

  < action android:value="android.intent.action.EDIT" 

  /> 

  < action android:value="android.intent.action.PICK" 

  /> 

  < category android:name="android.intent.category.DEFAULT" 

  /> 

  < data android:mimeType="vnd.android.cursor.dir/vnd.google.note" 

  /> 

  < /intent-filter> 

  这里面配置用到了action, data, category这些东西,那么聪明的你一定想到intent里也会有这些东西,然后一匹配不就找到接收者了吗? 

  action其实就是一个意图的字符串名称。 

  上面这段intent-filter的配置文件说明了这个Activity可以接受不同的Action,当然相应的程序逻辑也不一样咯,提一下那个 mimeType,他是在ContentProvider里定义的,你要是自己实现一个ContentProvider就知道了,必须指定 

mimeType才能让数据被别人使用。 

  不知道原理说明白没,总结一句,就是你调用别的界面不是直接new那个界面,而是通过扔出一个intent,让系统帮你去调用那个界面,这样就多么松藕合啊,而且符合了生命周期被系统管理的原则。 

  想知道category都有啥,Android为你预先定制好的action都有啥等等,请亲自访问官方链接Intent 

  ps:想知道怎么调用系统应用程序的同学,可以仔细看一下你的logcat,每次运行一个程序的时候是不是有一些信息比如: 

  Starting activity: Intent { action=android.intent.action.MAINcategories={android.intent.category.LAUNCHER} flags=0x10200000comp={com.android.camera/com.android.camera.GalleryPicker} } 

13、 如何退出Activity?如何安全退出已调用多个Activity的Application?

1,借助系统的API 

首先,2.2以前和2.2以后采用的方法是不同的。但都是针对系统级别的东西进行操作。从进程和包的角度来达到此效果。 

所以需要添加授权,但是遗憾的是,这些方法涉及底层,而且在我们的应用中是起不到效果的。 这个方案被我排除了。 


2,抛出异常,Force Close 

这个我觉得很不靠谱。这确实能一下子退出应用。 

但是,其一:不能保证所有的Activity都被finish;其二:Force Close的窗口,这个是很糟糕的,当然可以重写一些方法,使不弹出这个窗口。 

这个方案也被我排除了。 


3,递归退出 

使用startActivityForResult打开新的Activity,并加上标识。 

在onActivityResult中进行处理,递归关闭。 

这个方式我不是很清楚其具体做法,感觉有些复杂。 


4,发送特定广播 

这个办法是我最赞同的,但是实际操作起来确遇到了问题。 

首先看onReceive(Context context, Intent intent)方法, 

可以通过context取得ActivityManager,之后取得当前运行的task的信息,看起来离成功不远了。 

Activity是被组织在task中的,获得了task信息,那是不是就可以取得其中的Activity实例? 

先看看代码: 


//通过context获取系统服务,得到ActivityManager

ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

//获取当前运行中的TaskInfo 

//获取的是一个List集合,也就是说当前系统中的task有多个,在我测试代码中有2个

//关于该方法的参数,我从源码看了下,是指返回集合的最大可能条目数,实际返回数可能

//小于这个数目,取决于用户启动了几个task

List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(10);


包含task信息的是一个ActivityManager的静态内部类,RunningTaskInfo。 

不过从中能取得的信息有限: 


//task栈底的Activity

ComponentName baseActivity = task.baseActivity;

//task栈顶的Activity

ComponentName topActivity = task.topActivity;


这就有两个问题, 

其一,无法取得task中的每一个Activity 

其二,不能取得Activity的实例 

我的研究到此止步,希望有达人能为我解惑。 


5,记录每一个创建的Activity,这也是我最后采用的方法。 

为入口Activity添加一个静态的List<Activity>, 

之后,每一个Activiity的onCreate方法中,将自身加入这个List, 

当程序退出时,遍历这个List,执行finish方法 


    for (Activity act : MainActivity.tasks) {

           if(!act.isFinishing()){

              act.finish();

           }

       }

       MainActivity.tasks = null;


测试了一下,能达到效果。 

但是还是有一点担心,这就是Activity成员变量的生命周期问题, 

当该成员变量的生命周期大于Activity的生命周期,就有可能造成内存泄露。

14、 请介绍下Android中常用的五种布局

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


   一、FrameLayout

    这个布局可以看成是墙脚堆东西,有一个四方的矩形的左上角墙脚,我们放了第一个东西,要再放一个,那就在放在原来放的位置的上面,这样依次的放,会盖住原来的东西。这个布局比较简单,也只能放一点比较简单的东西。    


    二、LinearLayout

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

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

)。当垂直布局时,每一行就只有一个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次向右排列。  linearLayout中有一个重要的属性 android:layout_weight="1",这个weight在垂直布局时,代表行距;水平的时候代表列宽;weight值越大就越大。    

    三、AbsoluteLayout    

绝对布局犹如div指定了absolute属性,用X,Y坐标来指定元素的位置android:layout_x="20px" 

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

     四、RelativeLayout

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

        相对于某一个元素

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

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

        相对于父元素的地方

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

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

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

五。TableLayout

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

15、 请介绍下Android的数据存储方式

Android提供了5种方式存储数据:

1.使用SharedPreferences存储数据;

2.文件存储数据;

3.SQLite数据库存储数据;

4.使用ContentProvider存储数据;

5.网络存储数据;

其中3,4已经在Android SQLite解析、Android 应用程序之间数据共享篇幅中详细说明,不在此重复说明,现将其他3种方式详细介绍。

使用SharedPreferences存储数据

首先说明SharedPreferences存储方式,它是Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下:

void  ReadSharedPreferences()

{

String  strName,strPassword;

SharedPreferences   user = getSharedPreferences(“user_info”,0);

strName = user.getString(“NAME”,””);

strPassword = user getString(“PASSWORD”,””);

}

void  WriteSharedPreferences(String  strName,String strPassword)

{

SharedPreferences   user = getSharedPreferences(“user_info”,0);

uer.edit();

user.putString(“NAME”, strName);

user.putString(“PASSWORD” ,strPassword);

user.commit();

}

数据读取与写入的方法都非常简单,只是在写入的时候有些区别:先调用edit()使其处于编辑状态,然后才能修改数据,最后使用commit()提交修改的数据。实际上SharedPreferences是采用了XML格式将数据存储到设备中,在DDMS中的File Explorer中的/data/data/<package name>/shares_prefs下。以上面的数据存储结果为例,打开后可以看到一个user_info.xml的文件,打开后可以看到:

<?xml version=”1.0″ encoding=”UTF-8″?>

<map>

<string name=”NAME”>moandroid</string>

<string name=” PASSWORD”>SharedPreferences</string>

</map>

使用SharedPreferences是有些限制的:只能在同一个包内使用,不能在不同的包之间使用。

文件存储数据

文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件。FilterInputStream, FilterOutputStream等可以到Java  io  package说明中去详细学习,不再此详细说明,具体实例如下:

String fn = “moandroid.log”;

FileInputStream fis = openFileInput(fn);

FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);

除此之外,Android还提供了其他函数来操作文件,详细说明请阅读Android SDK。

网络存储数据

网络存储方式,需要与Android 网络数据包打交道,关于Android 网络数据包的详细说明,请阅读Android SDK引用了Java SDK的哪些package?。

总结说明

以上5中存储方式,在以后的开发过程中,根据设计目标、性能需求、空间需求等找到合适的数据存储方式。Android 中的数据存储都是私有的,其他应用程序都是无法访问的,除非通过ContentResolver获取其他程序共享的数据。

16、 请介绍下ContentProvider是如何实现数据共享的

Android是如何实现应用程序之间数据共享的?一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和这个程序里的数据打交道,例如:添加(insert)、删除(delete)、查询(query)、修改(update),当然需要一定的权限才可以。

如何将应用程序的数据暴露出去? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。

17、 如何启用Service,如何停用Service。

一.步骤

第一步:继承Service类

public class SMSService extends Service { }


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

<service android:name=".DemoService" />

二.Context.startService()和Context.bindService


服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可

以启动Service,但是它们的使用场合有所不同。


1.使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。


使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。


2.采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,


接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。


采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。


3.采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,


接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。


1.Service常用生命周期回调方法如下:

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


服务也只被创建一次。 onDestroy()该方法在服务被终止时调用。


2. Context.startService()启动Service有关的生命周期方法


onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。


多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。

3. Context.bindService()启动Service有关的生命周期方法


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


当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。


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


备注:


1.       采用startService()启动服务    

Intent intent = new Intent(DemoActivity.this, DemoService.class);

   startService(intent);

2.       Context.bindService()启动

Intent intent = new Intent(DemoActivity.this, DemoService.class);

    bindService(intent, conn, Context.BIND_AUTO_CREATE);

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


18、 注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意

两种:一种是XML,一种是代码注册

      Xml注册的优点是:方便,易读

      缺点是当手机处于关机状态时,仍然可以监听到广播,不灵活

      代码注册的优点:灵活,手机处于关机状态时,不在监听广播

          缺点:不方便,不容易读

1.    请描述下Activity的生命周期。


      答:onCreate(),Activity第一次加载时调用,用户构建窗体。


           onStart()Activity能被用户看到时调用


           onResume()Activity能够得到用户焦点时调用


           onRestart()Activity第二次被加载时调用,不在调用onCreate()


           onPause()Activity在启动另一个activity时调用,推动用户焦点


           onStop()Activity被第二个activity完全覆盖时调用


           onDestory()Activity被第二个ActivitY从栈中取出时调用,也可以说第二个Activity反回第一个Activity时,Activity的onDestory,销毁Activity。



2.    如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?


       答:在系统回收或者用户调用Finish方法 ,都会销毁Activity,此时会调用Ondestory方法,利用onDestory方法保存Activity状态。


3.    如何将一个Activity设置成窗口的样式。(Edited by Sodino)


     答:在androidMinifest.xml文件中配置Activity的属性的主题为:


            Android:theme="@android:style/Theme.Dialog"


4.    如何退出Activity?如何安全退出已调用多个Activity的Application?


     答:单个的activity调用Finish,killprocess(),system.exit()方法退出


         多个Activity


          在2.1之前,可以使用ActivityManager的RestartPackage方法


          它可以直接结束整个应用,在使用时需要权限android.permission.RESTART_PACKAGES


           在2.2这个方法失效了,新添加了一个方法,killBackgroundProcesses().需要权限android.permission.KILL_BACKGTOUND_PROCESSE


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


答:LinearLayout线性布局


    RelativeLayout相对布局


    AbsoluteLayout根据坐标布局


    TableLayout表格布局


    FrameLayout帧布局


6.    请介绍下Android的数据存储方式。(Edited by Sodino)


     答:sharedPreferences键值对的存储


         Sqllite数据库存储


         Files文件存储


         NetWork网络存储


7.    请介绍下ContentProvider是如何实现数据共享的。(Edited by Sodino)


      答:ContentProvider负责:组织应用程序的数据,向其他应用程序提供数据;


           ContentResolver负责:获取ContentProvider提供的数据,CRUD数据。


8.    如何启用Service,如何停用Service。(Edited by Sodino)


      答:启动Service


         Intent intent = new Intent(this,MyService.class);


         startService(intent);//启动服务的调用者跟服务没有任何关系,调用者退出服务不会有任何影响


         bindService(intent)//启动后的调用者跟服务绑定在一起,调用者一点退出,服务也会终止


           停用Service


       stopServcie(intent)


       unbindService(intent)


9.    注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。


      答:两种:一种是XML,一种是代码注册


           Xml注册的优点是:方便,易读


           缺点是当手机处于关机状态时,仍然可以监听到广播,不灵活


          代码注册的优点:灵活,手机处于关机状态时,不在监听广播


          缺点:不方便,不容易读


10.    请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系。


          答:Message Queue(消息列队):用来存放通过Handler发布的消息,通常附属于某一创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列


       Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发磅到与它关联的消息队列,然也只能处理该消息队列中的消息


        Looper:是Handler和消息队列之间通讯的桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列,Looper也把消息队列里的消息广播给所有的Handler,handler接受到消息后调用HandlerMessage进行处理


        Message:消息的类型 ,在Handler类中的HandlerMessage方法中得到单个的消息进行处理


11.    AIDL的全称是什么?如何工作?能处理哪些类型的数据?




12.    请解释下Android程序运行时权限与文件系统权限的区别。(Edited by Sodino)


13.    系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由。


14.    有一个一维整型数组int[]data保存的是一张宽为width,高为height的图片像素值信息。请写一个算法,将该图片所有的白色不透明(0xffffffff)像素点的透明度调整为50%。


15.    你如何评价Android系统?优缺点。


答:优点:1、学习的开源性

   2、软件兼容性比较好

   3、软件发展迅速

   4、界面布局好

   缺点:1、版本过多

   2、先有软件少

   3、商务性能差


20、简述Andrid应用程序的结构是哪些?

答:Linux Kernel(Linux 内核)、Libraries(系统运行类库或者C/C++核心库)、Application Framawork(开源框架)、Applications(核心应用程序)

21、什么是ANR,如何避免它?

答:ANR(Application Not Responding):应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应的对话框

避免ANR:Android应用程序通常运行在一个单独的线程里面,称谓主线程,所以在主线程里面少做一些耗时长的程序,而是利用子线程来操作一些繁琐的事情,用Handler来把子线程处理的消息返回给主线程

22、简要解释一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver

答:activity呈现了一个用户可以操作的可视化用户界面

service不包含可见的用户界面,而是在后台无限地运行可以连接到一个正在运行的服务中,连接后,可以通过服务中暴露出来的借口与其进行通信

broadcast receiver是一个接收广播消息并作出回应的component,broadcast receiver没有界面

intent:content provider在接收到ContentResolver的请求时被激活。

activity, service和broadcast receiver是被称为intents的异步消息激活的。

一个intent是一个Intent对象,它保存了消息的内容。对于activity和service来说,它指定了请求的操作名称和待操作数据的URIIntent对象可以显式的指定一个目标component。如果这样的话,android会找到这个component(基于manifest文件中的声明)并激活它。但如果一个目标不是显式指定的,android必须找到响应intent的最佳component。它是通过将Intent对象和目标的intent filter相比较来完成这一工作的。一个component的intent filter告诉android该component能处理的intent。intent filter也是在manifest文件中声明的


1、什么是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。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。 

  2、什么情况会导致Force Close ?如何避免?能否捕获导致其的异常? 

  答:一般像空指针啊,可以看起logcat,然后对应到程序中 来解决错误 

  3、Android本身的api并未声明会抛出异常,则其在运行时有无可能抛出runtime异常,你遇到过吗?诺有的话会导致什么问题?如何解决? 

  4、简要解释一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver 

  答:一个activity呈现了一个用户可以操作的可视化用户界面 

  一个service不包含可见的用户界面,而是在后台无限地运行 

  可以连接到一个正在运行的服务中,连接后,可以通过服务中暴露出来的借口与其进行通信 

  一个broadcast receiver是一个接收广播消息并作出回应的component,broadcast receiver没有界面 

  intent:content provider在接收到ContentResolver的请求时被激活。 

  activity, service和broadcast receiver是被称为intents的异步消息激活的。 

一个intent是一个Intent对象,它保存了消息的内容。对于activity和service来说,它指定了请求的操作名称和待操作数据的URI 

  Intent对象可以显式的指定一个目标component。如果这样的话,android会找到这个component(基于manifest文件中的声明)并激活它。但如果一个目标不是显式指定的,android必须找到响应intent的最佳component。 

  它是通过将Intent对象和目标的intent filter相比较来完成这一工作的。一个component的intent filter告诉android该component能处理的intent。intent filter也是在manifest文件中声明的。 

  5、IntentService有何优点? 

  答:IntentService 的好处 

  * Acitivity的进程,当处理Intent的时候,会产生一个对应的Service 

  * Android的进程处理器现在会尽可能的不kill掉你 

  * 非常容易使用 

  6、横竖屏切换时候activity的生命周期? 

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

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

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

  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数据库文件。 

  3. Android引入广播机制的用意? 

  答:a:从MVC的角度考虑(应用程序内) 

  其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。 

  b:程序间互通消息(例如在自己的应用程序内监听系统来电) 

  c:效率上(参考UDP的广播协议在局域网的方便性) 

  d:设计模式上(反转控制的一种应用,类似监听者模式)



 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics