android 常见面试题以及答案

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

Activity 的生命周期与activity的活动状态密切相关,也和activity的周期函数密切相关 

共有七个周期函数: 

void onCreate(Bundle savedInstanceState) 

void onStart() 

void onRestart() 

void onResume() 

void onPause() 

void onStop() 

void onDestroy() 


1.完整生命周期:      即一个activity从出现到消失,对应的周期方法是从onCreate到onDestroy 

2.可见生命周期:      从onStart()到onStop()方法,在这个周期中,用户可以看见Activity,但不一定能够与之交互,这两个方法可以随着状态的变化被执行多次。 

3.前景生命周期:       从onResume()到onPause()方法,在这个周期中,Activity处在其它Activity之前,即在Activity栈的最顶端,负责与用户进行交互,伴随着状态的变化,这两个方法可以被执行多次。 

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

onSaveInstanceState() 当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成以后又会来找A,

这个时候就有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。

 另外,刚才查看了一下Activity的源码,发现Activity还有个onRestoreInstanceState(Bundle outState)方法.这个方法的描述中也写到在Activity回复先前保存的状态时会被调用.

  当一个Activity被pause或者stop的时候,这个Activity的对象实际上还是保存在内存中,因此这个Activity中的信息(成员和状态信息)还可以重新获取到. 

    如果系统为了整理内存而销毁了整合各Activity对象时,系统没法简单的原封不动地恢复先前的Activity对象及其状态信息. 

    从android手册上来看,Activity中提供了一个方法:onSavedInstanceState(Bundle obj).当系统销毁一个Activity时,会将Activity的状态信息已键值对形式存放在bundle对象中. 

    第一次启动Activity时,这个bundle对象是空的,null.如果Activity被系统销毁了,然后用户要回退回去看的话,系统会调用这个Activity的onCreate方法,并把bundle对象传递过去. 

    这个函数有默认的行为,因此就算你不覆盖它,它在Activity中也有实现. 

    这回我总算明白了为什么onCreate方法的定义是"protected void onCreate (Bundle savedInstanceState)"这个样子的了. 

    另外,刚才查看了一下Activity的源码,发现Activity还有个onRestoreInstanceState(Bundle outState)方法.这个方法的描述中也写到在Activity回复先前保存的状态时会被调用.


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

做法有两种

1.在AndroidManifest.xml文件当中设置当前activity的一个属性(系统自带的属性):

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

    

效果图:

如何将一个Activity设置成窗口的样式(面试题) - zhou_411424 - 惜世缺麟的博客

 

    方法2.

 1。在你的styles.xml文件中可以新建一如下的style:

    <style name="Theme.FloatActivity" parent="android:style/Theme.Dialog">

        <!-- float_box为我们定义的窗口背景 ,这个不是必须的-->

        <item name="android:windowBackground">@drawable/float_box</item>

    </style>

如果窗口要添加窗口背景,可以在drawable中新建一个叫float_box.xml的文件,内容可以如下(自定义):

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#ffffff" />

    <stroke android:width="3dp" color="#000000" />

    <corners android:radius="3dp" />

    <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />

</shape>

2.在AndroidManifest.xml中在你需要显示为窗口的activity中添加如果属性:android:theme="@style/Theme.FloatActivity" 即可

效果如图:

如何将一个Activity设置成窗口的样式(面试题) - zhou_411424 - 惜世缺麟的博客


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

对于单一Activity的应用来说,退出很简单,直接finish()即可。 

当然,也可以用killProcess()和System.exit()这样的方法。 


但是,对于多Activity的应用来说,在打开多个Activity后,如果想在最后打开的Activity直接退出,上边的方法都是没有用的,因为上边的方法都是结束一个Activity而已。 

当然,网上也有人说可以。 

就好像有人问,在应用里如何捕获Home键,有人就会说用keyCode比较KEYCODE_HOME即可,而事实上如果不修改framework,根本不可能做到这一点一样。 

所以,最好还是自己亲自试一下。 


那么,有没有办法直接退出整个应用呢? 

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

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

注意不要被它的名字迷惑。 


可是,在2.2,这个方法失效了。 

在2.2添加了一个新的方法,killBackgroundProcesses(),需要权限 android.permission.KILL_BACKGROUND_PROCESSES。 

可惜的是,它和2.2的restartPackage一样,根本起不到应有的效果。 


另外还有一个方法,就是系统自带的应用程序管理里,强制结束程序的方法,forceStopPackage()。 

它需要权限android.permission.FORCE_STOP_PACKAGES。 

并且需要添加android:sharedUserId="android.uid.system"属性 

同样可惜的是,该方法是非公开的,他只能运行在系统进程,第三方程序无法调用。 

因为需要在Android.mk中添加LOCAL_CERTIFICATE := platform。 

而Android.mk是用于在Android源码下编译程序用的。 


从以上可以看出,在2.2,没有办法直接结束一个应用,而只能用自己的办法间接办到。 


现提供几个方法,供参考: 


1、抛异常强制退出: 

该方法通过抛异常,使程序Force Close。 

验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。 


2、记录打开的Activity: 

每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。 


3、发送特定广播: 

在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。 


4、递归退出 

在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。 


除了第一个,都是想办法把每一个Activity都结束掉,间接达到目的。 

但是这样做同样不完美。 

你会发现,如果自己的应用程序对每一个Activity都设置了nosensor,在两个Activity结束的间隙,sensor可能有效了。 

但至少,我们的目的达到了,而且没有影响用户使用。 


为了编程方便,最好定义一个Activity基类,处理这些共通问题。

下面是转载的一片文章 

Android之完美退出方法(2.1-2.2-2.3SDK版本测试通过)[转] 

因为网上有很多种退出方法,可是实际上很多方法都不通用(在某个版本下可用,到了另一个版本就不行),或者方法的实际效果根本就和其描述不符(也不知道那些发帖的人测没测试过)。 


但我们的需求又确实存在。在某些情况下,我们需要在应用中打开多个Activity,但如果仅仅使用finish()方法就不能在需要的时候达到一次性退 出的效果,自己作为一个Android退出问题的受害者,通过良久思考和实际测试,找到了一个比较不错的,在2.1-2.2-2.3版本下都通用的完全退 出方法(2.1版本也基本可以代表1.5~2.1版本)!

 

PS:测试全部在模拟器环境下进行 

我首先进行一下说明,下面两种方法效果完全相同 
1,android.os.Process.killProcess(android.os.Process.myPid()) ; (这是Dalvik VM的本地方法) 
2,System.exit(0); (常规java、c#的标准退出法,返回值为0代表正常退出 ) 
之后我的说明全部以android.os.Process.killProcess(android.os.Process.myPid()) 方法为准。 

另外,我后边所说的程序入口即为在AndroidManifest.xml中配置为如下语句的Activity


PS:测试全部在模拟器环境下进行 


我首先进行一下说明,下面两种方法效果完全相同 

1,android.os.Process.killProcess(android.os.Process.myPid()) ; (这是Dalvik VM的本地方法) 

2,System.exit(0); (常规java、c#的标准退出法,返回值为0代表正常退出 ) 

之后我的说明全部以android.os.Process.killProcess(android.os.Process.myPid()) 方法为准。 


另外,我后边所说的程序入口即为在AndroidManifest.xml中配置为如下语句的Activity

 

<action android:name="android.intent.action.MAIN" />

 

<category android:name="android.intent.category.LAUNCHER" />

 


下面开始我们的Android完美退出之旅:

 
先从网上的一段说明说起: 
A->B 
B中执行android.os.Process.killProcess(android.os.Process.myPid()); 
结果是结束了B,然后重新启动A。 
实际情况是这样:A为程序入口,B中调用killProcess(android.os.Process.myPid())操作,实际上是将程序入口A和执行该语句的Activity B都关闭,并重新启动新的程序入口A。 
所以,如果过程是A->B->C 
则实际情况是:A为程序入口,C中调用killProcess(android.os.Process.myPid())操作将程序入口A和执行该语句的Activity C都关闭,并重新启动新的程序入口A(在Activity窗口历史栈当中,旧A 被关闭,新A 仍然会被放置在 旧A 所在的栈位置,不会到达栈顶端)。 

先从网上的一段说明说起: 

A->B

 

B中执行android.os.Process.killProcess(android.os.Process.myPid());

 

结果是结束了B,然后重新启动A。

 

实际情况是这样:A为程序入口,B中调用killProcess(android.os.Process.myPid())操作,实际上是将程序入口A和执行该语句的Activity B都关闭,并重新启动新的程序入口A。 

所以,如果过程是A->B->C 

则实际情况是:A为程序入口,C中调用killProcess(android.os.Process.myPid())操作将程序入口A和执行该语句的Activity C都关闭,并重新启动新的程序入口A(在Activity窗口历史栈当中,旧A 被关闭,新A 仍然会被放置在 旧A 所在的栈位置,不会到达栈顶端)。 


PS: 

如果killProcess(android.os.Process.myPid())或System.exit(0)是在程序入口A处执行,则是将入口A关闭,不会再开启新的A. 

有人要问了,B Activity呢? 


有人要问了,B Activity呢? 

B还存在着,B Activity没有被关闭。 
如何解决这个问题? 
首先说明一点 
android.os.Process.killProcess(android.os.Process.myPid()) ;语句执行之后,后边的代码都将不再执行; 
而finish();或startActivity(A.this,B.class);语句在执行完成后仍旧会执行后续的代码。(使用Thread.sleep多次验证,不用担心finish()过后不能startActivity了,相反也一样)。 
所以,我们就可以充分利用这一点,既然finish();和startActivity(A.this,B.class);语句在执行后仍然可以执行后续代码操作,那我们可以将之组合在一个代码片段中,即 
startActivity(new Intent(B.this, C.class)); 
finish(); 
或 
finish(); 
startActivity(new Intent(B.this, C.class)); 
都是可以的,我们在B中使用该代码段,既将B Activity关闭了,也打开了C Activity,之前的问题Done! 
如果你还有D,E,F ... 那也一样,在每次跳转到下一个Activity时,将finish()一块用上。使用这种方式,多余的Activity就能够被关闭了。 

PS:很囧的是,在我自己的Android应用中,在程序入口处调用这种组合代码,会直接将新开启的Activity也一并关闭,但在我创建的简单工程当中却不会有这种情况,不知道为什么,还在寻找原因中......(也请高手指点一二) 


最后 假设我们有下面一种需求,对上边的内容进行总结: 
Activity的开启过程为 1.Index --> 2.A_Activity --> 3.B_Activity --> 4.Index,在4.Index中实现退出,Index为程序入口。 

Index 
退出:就是最简单的finish(); 
跳转:也是最简单的 startActivity(new Intent(Index.this, A_Activity.class)); 

A_Activity 
退回到首界面:分两种情况 
1,需要Index更新(我的Index就有这个需求,首页面色彩发生变化) 
使用android.os.Process.killProcess(android.os.Process.myPid()) ;关闭自己和之前的Index,创建新的Index; 
2,不需要新的Index,Index无变化 
使用最简单的finish(),并且效率还要高些。 
跳转: 
finish(); 
startActivity(new Intent(A_Activity.this, C.class)); 
关闭自身,开启除 Index 之外的其它Activity。 

B_Activity 
操作与 A_Activity 相同。当然跳转语句变成了 
finish(); 
startActivity(new Intent(B_Activity.this, Index.class)); 



************************************************************************** 

如何解决这个问题? 

首先说明一点 

android.os.Process.killProcess(android.os.Process.myPid()) ;语句执行之后,后边的代码都将不再执行;

 

而finish();或startActivity(A.this,B.class);语句在执行完成后仍旧会执行后续的代码。(使用Thread.sleep多次验证,不用担心finish()过后不能startActivity了,相反也一样)。

 

所以,我们就可以充分利用这一点,既然finish();和startActivity(A.this,B.class);语句在执行后仍然可以执行后续代码操作,那我们可以将之组合在一个代码片段中,即 

startActivity(new Intent(B.this, C.class)); 

finish(); 

或 

finish(); 

startActivity(new Intent(B.this, C.class)); 

都是可以的,我们在B中使用该代码段,既将B Activity关闭了,也打开了C Activity,之前的问题Done! 

如果你还有D,E,F ... 那也一样,在每次跳转到下一个Activity时,将finish()一块用上。使用这种方式,多余的Activity就能够被关闭了。 


PS:很囧的是,在我自己的Android应用中,在程序入口处调用这种组合代码,会直接将新开启的Activity也一并关闭,但在我创建的简单工程当中却不会有这种情况,不知道为什么,还在寻找原因中......(也请高手指点一二) 



最后 假设我们有下面一种需求,对上边的内容进行总结:

 

Activity的开启过程为 1.Index --> 2.A_Activity --> 3.B_Activity --> 4.Index,在4.Index中实现退出,Index为程序入口。 


Index

 

退出:就是最简单的finish(); 

跳转:也是最简单的 startActivity(new Intent(Index.this, A_Activity.class)); 


A_Activity

 

退回到首界面:分两种情况 

1,需要Index更新(我的Index就有这个需求,首页面色彩发生变化) 

使用android.os.Process.killProcess(android.os.Process.myPid()) ;关闭自己和之前的Index,创建新的Index; 

2,不需要新的Index,Index无变化 

使用最简单的finish(),并且效率还要高些。 

跳转: 

finish(); 

startActivity(new Intent(A_Activity.this, C.class)); 

关闭自身,开启除 Index 之外的其它Activity。 


B_Activity

 

操作与 A_Activity 相同。当然跳转语句变成了 

finish(); 

startActivity(new Intent(B_Activity.this, Index.class)); 




************************************************************************** 

上边的内容就是这样了,下面我再告诉你另外一种方法,可以实现不关闭中途的Activity,而是在后边的操作中一次性关闭前边开启的所有Activity,可以满足一些人通过按返回键返回上一个界面的要求!

 

通过Android的窗口类提供的历史栈,巧妙利用stack的原理,我们在Intent中加入标志 Intent.FLAG_ACTIVITY_CLEAR_TOP。

 


Intent intent = new Intent();

 

intent.setClass(One.this, Two.class); 

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

startActivity(intent);

 


假定有如下需求:

 

1.Index --> 2.A_Activity --> 3.B_Activity

 


在3中设置 intent.setClass(B_Activity.this, Index.class);

 

跳转后,程序会从栈顶逐个向后查找,直到找 到栈中最近的Index,然后将这一路找到的Activity全部关闭,包括1、2、3(也就不需要像我先前的方法一路finish了,也保留了途中经过 的Activity),最后再自动建一个新的Index Activity放到栈顶的位置,接下来在Index窗口中使用finish方法即可退出。 


如果没有理解,看这个例子:

 

如果3中设置的是 intent.setClass(B_Activity.this, A_Activity.class);

 

则是将2,3关闭,再新建一个4.A_Activity,栈中就变成了

 

1.Index --> 4.A_Activity,懂了吧! 

值得注意的是,在下面的情况中 

1

.Index --> 2.A_Activity --> 3.B_Activity --> 4.Index --> 5.A_Activity 

在5中使用intent.setClass(A_Activity.this, B_Activity.class);

 

结果不是 

1.Index --> 2.A_Activity --> 6.B_Activity 

而是 

1.Index --> 2.A_Activity --> 3.B_Activity --> 4.Index--> 5.A_Activity --> 6.B_Activity,因为4(程序入口)的存在,所以5对栈的操作不会到达3,而是发现4、5中都没有B_Activity后,没有关闭任何 Activity,只在栈顶端新建了一个6.B_Activity。 

这也间接说明了Dalvik虚拟机的遍历算 法只进行到最近的程序入口,就认为后边没有该程序的Activity了。所以良好的Android编程习惯是,新建一个程序入口时,一定把老程序入口关 掉,这也解释了为什么用killProcess方法更新后的程序入口Index一定还是在栈中的老位置,而不是到栈顶端。

 


以上都是我通过新建的一个简单工程测试验证过的。 

不过很囧的是,这种退出方法,我在自己的应用程序下测试,结果都是直接退出到home界面,连Index界面都没有出现,还想请高手赐教一下这里边深层次的原因。 



************************************************************************** 

还有一种比较流行的Android经典完美退出方法,使用

单例模式创建一个Activity管理对象,该对象中有一个Activity容器(具体实现自己处理,使用LinkedList等)专门负责存储新开启的每一个Activity,并且容易理解、易于操作,非常不错! 
MyApplication类(储存每一个Activity,并实现关闭所有Activity的操作) 

MyApplication类(储存每一个Activity,并实现关闭所有Activity的操作)

 

public class MyApplication extends Application { 


private List<Activity> activityList = new LinkedList<Activity>(); 

private static MyApplication instance; 


private MyApplication() 

//单例模式中获取唯一的MyApplication实例

 

public static MyApplication getInstance() 

if(null == instance) 

instance = new MyApplication(); 

return instance; 

//添加Activity到容器中

 

public void addActivity(Activity activity) 

activityList.add(activity); 

//遍历所有Activity并finish

 

public void exit() 

for(Activity activity:activityList) 

activity.finish(); 

System.exit(0); 

在每一个Activity中的onCreate方法里添加该Activity到MyApplication对象实例容器中

 

MyApplication.getInstance().addActivity(this); 

在需要结束所有Activity的时候调用exit方法

 

MyApplication.getInstance().exit(); 


个人非常喜欢这种方法!(非常感谢flyrabbits

的帮助) 


—————————————分割线————————————————— 
我对其他一些退出方法进行的一点介绍和点评(不到之处还请指正): 
@



—————————————分割线————————————————— 

我对其他一些退出方法进行的一点介绍和点评(不到之处还请指正): 

@

restartPackage(getPackageName())(具体就不介绍了) 
我在SDK2.1版本下开发的一款小软件,放到Android2.2或2.3操作系统上无法退出,因为restartPackage方法在SDK2.1以 后版本已经被废弃不用了,理由是因为它不安全,可能关闭同其他应用程序共享的Service,而这个Service别人还要用呢,你给别人关了就不对了。 

@

我在SDK2.1版本下开发的一款小软件,放到Android2.2或2.3操作系统上无法退出,因为restartPackage方法在SDK2.1以 后版本已经被废弃不用了,理由是因为它不安全,可能关闭同其他应用程序共享的Service,而这个Service别人还要用呢,你给别人关了就不对了。 


@

有人说的终极退出方法: 
Intent startMain = new Intent(Intent.ACTION_MAIN); 
startMain.addCategory(Intent.CATEGORY_HOME); 
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(startMain); 
System.exit(0); 
实际上这种方法只是返回了Home页面,如果你再次进入应用,你会发现进入的首界面是你先前没有关闭的Activity。 

@

Intent startMain = new Intent(Intent.ACTION_MAIN); 

startMain.addCategory(Intent.CATEGORY_HOME); 

startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

startActivity(startMain); 

System.exit(0); 

实际上这种方法只是返回了Home页面,如果你再次进入应用,你会发现进入的首界面是你先前没有关闭的Activity。 


@

调用系统隐藏forceStopPackage方法,这里是通过映射调用(也有其他方法) 
Method method = null; 
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 
try { 
method = Class.forName("android.app.ActivityManager").getMethod("forceStopPackage", String.class); 
method.invoke(manager,getPackageName()); 
} catch (Exception e) { 
Log.d("force",e.getMessage()); 

我在SDK2.2和2.3的测试结果是,出现NULLPointerException,弹出错误窗口,程序被迫关闭,和预想的正常退出有差别。不过我们 可以通过修改基类实现自己的Thread.UncaughtExceptionHandler接口的uncaughtException方法,这样就不会 有错误窗口弹出。程序完全退出。 

@和上面一样,不过这是故意制造异常退出(上边是无意制造的异常),但我认为这毕竟是下策。

Method method = null; 

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 

try { 

method = Class.forName("android.app.ActivityManager").getMethod("forceStopPackage", String.class); 

method.invoke(manager,getPackageName()); 

} catch (Exception e) { 

Log.d("force",e.getMessage()); 

我在SDK2.2和2.3的测试结果是,出现NULLPointerException,弹出错误窗口,程序被迫关闭,和预想的正常退出有差别。不过我们 可以通过修改基类实现自己的Thread.UncaughtExceptionHandler接口的uncaughtException方法,这样就不会 有错误窗口弹出。程序完全退出。 


@

和上面一样,不过这是故意制造异常退出(上边是无意制造的异常),但我认为这毕竟是下策。

---------------------------------------------------------------------------------------------------

以上是网上的一些作法, 其实也可以通过intent的flag实现 , intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活一个新的acitvity,然后在新的activ ity的onCreate()方法里面finish掉.


5.    请介绍下Android中常用的五种布局。
6.    请介绍下Android的数据存储方式。(Edited by Sodino)
7.    请介绍下ContentProvider是如何实现数据共享的。(Edited by Sodino)
8.    如何启用Service,如何停用Service。(Edited by Sodino)
9.    注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。
10.    请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系。
11.    AIDL的全称是什么?如何工作?能处理哪些类型的数据?
12.    请解释下Android程序运行时权限与文件系统权限的区别。(Edited by Sodino)
13.    系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由。
14.    有一个一维整型数组int[]data保存的是一张宽为width,高为height的图片像素值信息。请写一个算法,将该图片所有的白色不透明(0xffffffff)像素点的透明度调整为50%。
15.    你如何评价Android系统?优缺点。

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

DVM 执行时,在linux看来就是一应用程序进程,所以说是同一概念


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

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


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

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


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

分 硬实时和软实时,android属于linux内核,linux在用户空间可抢占,内核空间在2.4以后可局部抢占,严格来讲 Android属于软实时系统


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

 


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都会自动更新。类似的,只要Controller改变了View,View会 从潜在的Model中获取数据来刷新自己。


一,listview你是怎么优化的。
二,view的刷新,之前说过
三,IPC及原理
四,Android多线程6 n; 
五,Android为什么要设计4大组件,他们之间的联系,不设计行不行(主要是为了实现MVC模式,然而java中最难的模式也是这个,很少有产品能将这个模式做得很好【Technicolor的面试官问的这个】)  
六,service的周期,activity的周期,谈下你对Android内部应用的了解,比如他做电话,以及联系人等等应用。框架层有很多东西还是多看看,熟悉Android怎么做的,不管你做应用程开发还是应用框架层开发很有好处的。
在就是你项目经验,突出你遇到什么难点,然后是怎么解决的!尽量将每个技术点凸显出来,当然面试官有时候会为了体现你是否真正做过,他会问你,你在这个应用中做那个模块,用了多少个类之类的问题。
偶尔有的面试官会问你,你用过Android自带的单元测试了没,怎么用的?
当然我面试过很多家单位,有的是做平板,手机,数字电视,有的是做出个erp之类的客户端等等,出于前面的三个,基本上都是将Android的全部改掉,如果真正要做Android的话,大家要学的还很多。
总之,一句话,什么样的面试官都有,去面试的时候要做好一切心理准备,不管是技术还是基础都得扎实。一个人的交谈能力也很重要,总之不是非常标准的普通话,最起码你说的得让别人听得懂,而且得把面试官讲得非常彻底,这样你获得offer的机会更大,谈工资也有优势~~当然曾经一家公司的面试官跟我说过,技术是不惜钱的,只要你有能力,多少钱他都请。

确实,来北京求职期间,牛人真的很多,而且有的面试官也非常好,给了很多忠肯的意见。并不是每个面试官都特想为难你的~最主要的还是想知道你的技术,因为他们也是吃公司饭,得为这个负责。

View重绘和内存泄露的好像是面试经常问的问题 
1. View的刷新: 
在需要刷新的地方,使用handle.sendmessage发送信息,然后在handle的getmessage里面执行invaliate或者postinvaliate. 
2. GC内存泄露 
出现情况: 
1.数据库的cursor没有关闭 
2.构造adapter时,没有使用缓存contentview 
   衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程/ 
3.Bitmap对象不使用时采用recycle()释放内存 
4.activity中的对象的生命周期大于activity 
调试方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size] 
还有其他问题,大家欢迎提出阿,可以是整体架构的,还有这个Hal层.

这篇文章会涉及到以下几个内容

一 Activity的生命周期 
二 让Activity变成一个窗口:Activity属性设定 
三 你后台的Activity被系统 回收怎么办:onSaveInstanceState 
四 调用与被调用:我们的通信使者 - Intent

一 Activity的生命周期


   和其他手机 平台 的应用 程序 一样,Android的应用程序 的生命周期是被统一掌控 的,也 
   就是说我们写的应用程序命运掌握在别人(系统)的手里,我们不能改变它,只能学习 并 
   适应它。

简单地说一下为什么是这样:我们手机在运行 一个应用程序的时候,有可能打进来电话 
   发进来短信 ,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能 ,另 
   外系统也不允许你占用太多资源 ,至少要保证电话功能吧,所以资源不足的时候也就有可 
   能被干掉。

 如何优化Android中ListView滚动速度的方法

他是让你滚动的快点还是慢点?

慢的话:
   有个延迟加载数据的方法,在API的demo中。

要是让ListView滚动速度快的话,你可以这样告诉他:

  让他的手指在屏幕上迅速的上下滑动,当他的手指移动速度达到100px/0.1秒后,就可以看到快速滑动的效果了!~


Android的国际化与本地化
internationalization (国际化)简称 i18n,因为在i和n之间还有18个字符,localization(本地化 ),简称L10n。 一般说明一个地区的语言时,用 语言_地区的形式,如  zh_CN, zh_TW.
各国语言缩写  http://www.loc.gov/standards/iso639-2/php/code_list.php
国家和地区简写 http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
android 对i18n和L10n提供了非常好的支持。android没有专门的API来提供国际化,而是通过对不同resource的命名来达到国际化,同时这种命名方法还可用于对硬件的区分,如不同的新视屏用不同的图片。
      在eclipse的工程中,res目录有默认几项resource,如 drawable, layout,menu,values
其余还有
res/anim/   用来放置动画
res/xml/     用来放置style theme等xml定义。
res/raw/    用来放置data数据
 我们引用这些resource时候,在java代码中是通过R.resource_type.resource_name的方式来使用,如setTitle(R.string.main_title);
还有一种是在xml中直接引用,如
<TextView  
    android:id ="@+id/hello_view"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
     引用了名字为hello的字符串。当程序运行时,通过Resource类会装载strings.xml中名字为hello的字符串。但Resource类装载strings.xml时会根据当前手机的设置来选择装载哪一个xml文件。这些手机设置有

MCC and MNC, Language and region, Screen dimensions, Wider/taller screens, Screen orientation,Screen pixel density, Touchscreen type, SDK version,也就是说通过手机当前语言区域,屏幕的大小,屏幕像素,以及当前android sdk的版本号来选择。通过把strings.xml放置在以这些选项命名的文件夹下,Resource类就能正确的装载所需的字符串。
     我们以不同的local和region来做一次国际化,首先values表示默认的字符串,也即当Resource找不到匹配的资源时,默认使用values文件夹下的资源,其余 drawable等资源也是同样的。
   当命名这些文件夹的名字时,不同的选项用-分开,而且次序必须和 andorid 文档中table http://developer.android.com/guide/topics/resources/resources-i18n.html#AlternateResources
文件夹的命名必须都是小写字符,否则在一些大小敏感的文件系统中可能会出错,如果你用大写,eclipse的adt都会自动报错。小写字母r表示region的意思。 上图命名了中文简体和繁体以及默认选项,在strings.xml中除了字符串本身不一样,xml中定义该字符串的名字,id都是一样的。所以在代码或者xml中引用该资源时,只要引用名字即可或者id即可,程序启动时候Resource类回到相应的目录下去寻找正确的字符串(资源)
  通过在Settings中设置locale& Text 我们可以让Resource类来选择相应文件夹下的内容,
选择英语时候结果如下,也即选择了 values下的strings.xml
选择 chinese(china)时,也即选了 values-zh-rcn目录下的strings.xml
选择 chinese(taiwan)时,也即选了 values-zh-rtw目录下的strings.xml
 其余手机的选项,像屏幕的像素等都可以建立相应得目录。
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 横向进度条风格
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 内核也同时作为硬件和软件栈之间的抽象层。
 开机自动运行程序!
 Android实现开机自动运行程序2009-12-31 15:01:17.0        开机     自动     运行     程序   有些时候,应用需要在开机时就自动运行,例如某个自动从网上更新内容的后台service。怎样实现开机自动运行的应用?在撰写本文时,联想到高焕堂先生以“Don''t call me, I''ll call you back!”总结Android框架,真是说到点子上了。理解这句话的含义,许多有关Android平台上实现某种功能的问题,都能迎刃而解。
 使用场景:手机开机后,自动运行程序,在屏幕上显示"Hello. I started!"字样。
 背景知识:当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED。只要在程序中“捕捉”到这个消息,再启动之即可。记住,Android框架说:Don''t call me, I''ll call you back。我们要做的是做好接收这个消息的准备,而实现的手段就是实现一个BroadcastReceiver。
 代码解析:
 1、界面Activity:SayHello.java
 package com.ghstudio.BootStartDemo;
 import android.app.Activity;
 import android.os.Bundle;
 import android.widget.TextView;
 public class SayHello extends Activity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 TextView tv = new TextView(this);
 tv.setText("Hello. I started!");
 setContentView(tv);
 }
 }
 这段代码很简单,当Activity启动时,创建一个TextView,用它显示"Hello. I started!"字样。
 2、接收广播消息:BootBroadcastReceiver.java
 package com.ghstudio.BootStartDemo;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 
 public class BootBroadcastReceiver extends BroadcastReceiver {
 static final String ACTION = "android.intent.action.BOOT_COMPLETED";
 @Override
 public void onReceive(Context context, Intent intent) {
 if (intent.getAction().equals(ACTION)){
 Intent sayHelloIntent=new Intent(context,SayHello.class);
 sayHelloIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 context.startActivity(sayHelloIntent);
 }
 }
 }
 该类派生自BroadcastReceiver,覆载方法onReceive中,检测接收到的Intent是否符合BOOT_COMPLETED,如果符合,则启动SayHello那个Activity。
 3、配置文件:AndroidManifest.xml
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.ghstudio.BootStartDemo"
 android:versionCode="1"
 android:versionName="1.0">
 <application android:icon="@drawable/icon" android:label="@string/app_name">
 <activity android:name=".SayHello"
 android:label="@string/app_name">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <receiver android:name=".BootBroadcastReceiver">
 <intent-filter>
 <action android:name="android.intent.action.BOOT_COMPLETED" />
 </intent-filter>
 </receiver>
 </application>
 <uses-sdk android:minSdkVersion="3" />
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
 </manifest> 
 注意其中粗体字那一部分,该节点向系统注册了一个receiver,子节点intent-filter表示接收android.intent.action.BOOT_COMPLETED消息。不要忘记配置android.permission.RECEIVE_BOOT_COMPLETED权限。
 完成后,编译出apk包,安装到模拟器或手机中。关机,重新开机。
 如果是系统进程的话,需要加入init配置文件来启动,随着linux启动而启动
 
 注:还有一些关于Activity之间的数据传递与Intent的具体应用、Activity的生命周期等老师的PPT上已经都有了。具体的笔试题目前只有华为有笔试题,并且也只是一般的选择题,其余公司都是一些JAVA的基础题,只会在面试的时候问一些关于Android的题,并且有的公司经常问一些关于底层C库的调用与Android隐式API的题。

 

------------------------------
面试题目及其答案

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都会自动更新。类似的,只要Contro

9、Activity的生命周期

  和其他手机 平台 的应用 程序 一样,Android的应用程序 的生命周期是被统一掌控 的,也 就是说我们写的应用程序命运掌握在别人(系统)的手里,我们不能改变它,只能学习 并 适应它。 
  简单地说一下为什么是这样:我们手机在运行 一个应用程序的时候,有可能打进来电话 发进来短信 ,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能 ,另 外系统也不允许你占用太多资源 ,至少要保证电话功能吧,所以资源不足的时候也就有可 能被干掉。

  言归正传,Activity的基本生命周期如下代码 所示:

  Java代码

  1. public

  2. class MyActivity extends Activity {

  3. protected

  4. void onCreate(Bundle savedInstanceState);

  5.

  6. protected

  7. void onStart();

  8.

  9. protected

  10. void onResume();

  11.

  12. protected

  13. void onPause();

  14.

  15. protected

  16. void onStop();

  17.

  18. protected

  19. void onDestroy();

  20. }

  21.

  22.  public  class MyActivity extends Activity {

  protected   void onCreate(Bundle savedInstanceState);

  protected   void onStart();

  protected   void onResume();

  protected   void onPause();

  protected   void onStop();

 protected   void onDestroy();

  }

 
  你自己写的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]来处理多线程和界面交互的问题。这个我后面会讲一些,最近因为这些东西头已经很大了,等我理清思绪再跟大家分享。 ller改变了View,View会 从潜在的Model中获取数据来刷新自己。

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

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

  Xml代码

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

  2.

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

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

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

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

  Xml代码

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

  2.

  3. android:theme="@android:style/Theme.Translucent"

  android:theme="@android:style/Theme.Translucent"

  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 ,('_'换成'.' < --注意:这个是文章内容不是笑脸)就可以用在描述文件 中了,找找类定义和描述文件中的对应关系就都明白了。

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

  当你的程序中某一个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} }

  再对照一下Intent的一些set方法,就知道怎么调用咯,希望你喜欢:)

 

 

 


Android面试题

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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:设计模式上(反转控制的一种应用,类似监听者模式)

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值