2018-6月Android试题整理

2018-6月Android试题整理


牛客网—Android工程师能力评估测试

1.使用AIDL完成远程service方法调用下列说法不正确的是
  • aidl对应的接口名称不能与aidl文件名相同
  • aidl的文件的内容类似java代码
  • 创建一个Service,在服务的onBind(Intent intent)方法中返回实现了aidl接口的对象
  • aidl对应的接口的方法前面不能加访问权限修饰符

编写Aidl文件时,需要注意下面几点:

  1. 接口名和aidl文件名相同
  2. 接口和方法前不用加访问权限修饰符public,private,protect等,也不能用final,static
  3. Aidl默认支持的类型包括Java基本类型(int,long,boolean等)和(String,List,Map,CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作为参数或返回值,自定义类型必须实现Pracelable接口
  4. 自定义类型和AIDL生成的其他接口类型在aidl描述文件中,应该显示import,即便在该类和自定义的包在同一个包中
  5. 在aidl文件中所有非Java基本类型参数必须加上in,out,inout标记,以指明参数是输入参数,输出参数还是输入输出参数。
  6. Java原始类型默认的标记为in不能为其它标记。

2.关于ServiceConnection接口的onServiceConnected()方法的触发条件描述正确的是?
  • bindService()方法执行成功后
  • bindService()方法执行成功同时onBind()方法返回非空IBinder对象
  • Service的onCreate()方法和onBinder方法执行成功后
  • Service的onCreate()和onStartCommand()方法启动成功后

bindService是异步调用和Service进行绑定,如果绑定成功,则会调用ServiceConnection的onServiceConnected当调用bindService方法后就会回调Activity的onServiceConnected,在这个方法中会向Activity中传递一个IBinder的实例,Activity需要保存这个实例。

Android官方文档中对于onBinder()方法的解释:if you don’t want to allow binding, you should return null.(如果你不希望你的服务被绑定,那么你应该返回null)。测试确实如此,如果onBinder()方法返回Null那么onServiceConnected将不会被调用


3.遇到下列哪些情况时需要把进程移到前台?
  • 进程正在运行一个与用户交互的Activity,他的onResume()方法被调用
  • 进程有一个正运行的BroadcastReceiver,它的OnReceiver()方法正在执行
  • 进程有一个Service并且在Service的某个回调函数(onCreate(),onStart()或onDestory())内有正在执行的代码
  • 所有都正确
  • 进程有一个Service,该Service对应的Activity正在与用户交互。

进程按重要性分类,第一类进程最重要,通常最后被销毁

  1. 前台进程:与用户当前正在做的事情密切相关,不用的应用程序组件能够通过不同的方法使他的宿主进程移到前台。当下面任何一个条件满足时,可以考虑将进程移到前台:
    1. 进程正在运行一个与用户交互的Activity,它的onResume()方法被调用
    2. 进程有一个Service,该Service对应的Activity正在与用户交互
    3. 进程有一个Service被调用startForeground()方法,要求到前台来执行
    4. 进程有一个Service,并且在Service的某个回调函数(onCreate(),onStart(),或onDestory())内有正在执行的代码
    5. 进程有一正在运行的BroadcastRecevier,它的onReceiver()方法正在执行

或者可以说:只要主线程正在做事,那么即为前台进程。


4.使用Toast提示时,关于提示时长,下面说法正确的是()
  • 显示时长默认只有两种设置
  • 可以自定义显示时长
  • 传入30时,提示会显示30秒钟
  • 当自定义显示时长时,比如传入30,程序会抛出异常

Toast只能设置为2s和3,5s,其它的值都无效,API文档虽然写了三个,但是在Framework里做了重定义,限定了2s和3,5s这两个值,对应
Toast.LENGTH_SHORT和Toast.LENGTH_LONG。实现方式在NotificationManagerService.java的scheduleTimeoutLocked()这个函数里。

总的来说:Toast只能使用short和long两种时长,传进去自定义数字实际不起作用,想要更丰富的提示推荐使用Dialog。


5.Intent传递数据时,下列的数据类型哪些可以被传递?
  • Serializable
  • CharSequence
  • Farcelable
  • Bundle

都可以
Intent可以传递哪些类型的数据:

  1. 8中基本类型及其数组
  2. String(String实现了CharSequence)/CharSequence实例类型的数据及其数组
  3. 实现了Parcelable的对象及其数组
  4. 实现了Serializable的对象及其数组

ps:CharSequence接口的实现类有CharBuffer、String、StringBuffer、StringBuilder这个四个类。


6.在Android中使用Menu时可能需要重写的方法有?
  • onCreateOptionsMenu()
  • onCreateMenu()
  • onOptionsItemSelected()
  • onItemSelected()

上下文菜单(通过在某元素上长按,来呼出菜单)
选项菜单(通过按手机上的菜单按钮,来呼出菜单)

重写onCreateContextMenu用以创建上下文菜单
重写onCreateItemSelected用以响应上下文菜单

重写onCreateOptionsMenu用来创建选项菜单
重写onOptionsItemSelected用以响应选项菜单

当每次Menu显示时,回调用方法onPrepareOptionMenu,也可以在菜单每次被调用时,对菜单中的项重新生成,通过重载onPrepareOptionsMenu来实现,由于每次调用时都要重新生成,对于那些不经常变化的菜单,效率就会比较低。

总的来说:Android中有三种菜单

  1. 选项菜单Options menus:一个Activity只能有一个选项菜单,在按下Menu键时,显示在屏幕下方
  2. 上下文菜单Context menus:为Activity中的任何一个视图注册一个上下文菜单,“长按”出现。
  3. 弹出式菜单Popup menus:依赖于Activity中的某一个视图。

7.Android中使用SQLiteOpenHelper这个辅助类时,可以生成一个数据库,并可以对数据库进行管理的方法可以是?
  • getWriteableDatabase()
  • getReadableDatabase()
  • getDatabase()
  • getAbleDatabase()

Android使用getWriteableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。
(getReadableDatabase()方法中会调用getWriteableDatabase()方法)
getReadableDatabase()并不是以只读方式打开数据库,而是先执行getWriteableDatabase(),失败的情况下才以只读方式打开数据库。但getWriteableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,getWriteableDatabase()打开数据库就会出错,getReadableDatabase()方法先以读写方式打开数据库,倘若使用如果数据库的磁盘空间满了,就会打开失败。当打开失败后会继续尝试以只读方式打开数据库。


8.Android关于service生命周期的onCreate()和onStart()说法正确的是?
  • 当第一次启动的时候先后调用onCreate()和onStart()方法
  • 当第一次启动的时候只会调用onCreate()方法
  • 如果service已经启动,将先后调用onCreate()和onStart()方法
  • 如果service已经启动,只会执行OnStart()方法,不再执行onCreate()方法

9.下列对Android NDK的理解正确的是
  • NDK是一系列工具的集合
  • NDK提供了一份稳定,功能有限的API头文件声明
  • 使“java+c”的开发方式终于转正,成为官方支持的开发方式
  • NDK将是Android平台支持C开发的开端

Google宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android上,“Java+c”的编程方式是一直都可以实现的,NDK是Android支持C的开端说法是不正确的。
NDK是一系列工具的集合,NDK提供了一系列的工具,帮助开发者迅速的开发C/C++的动态库,并能自动将So和Java应用打成APK包。
NDK集成了交叉编译器,并提供了响应的mk文件和隔离cpu,平台等的差异,开发人员只需要简单的修改mk文件就可以创建出so


10.有关Activity生命周期描述正确的是
  • 设置Activity的android:screenOrientation=”portrait”属性时,切换屏幕横纵方向时不会重新调用各个生命周期,只会执行onConfigurationChange方法
  • 未设置Activity的android:configChanges属性,切换屏幕横纵方向时会重新调用onCreate()方法
  • 当再次启动某个launchMode设置为singletask的Activity,它的onNewIntent()方法会被触发
  • 用户正在操作某个Activity,这时如果其它应用程序需要内存,系统会将用户当前操作的Activity强制关闭。

解析:
A:设置Activity的android:screenOrientation=”portrait”属性时,无法切换横竖屏,因此不但不会重新调用各个生命周期方法,而且onConfigurationChanged()方法也不会执行
B:未设置Activity的android:configChanges属性,API上说“the activity will be restarted if any of these configuration changes happen in the system”,即如果配置有改变,就会重启activity
C:launchMode设置为singletask时,通过Intent启动一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再调用通常情况下我们处理请求数据的onCreate()方法,而是调用onNewIntent方法
D:用户正在操作某个Activity,这是如果其它应用程序需要内存,此时的Activity是Foreground process,应该按照Empty process,Back process,Service process,Visible process顺序kill,最后才是前台进程。

简单说:如果设置了android:configChanges=”oritation|screenSize”,并在activtiy中复写onConfigurationChanged方法,就不会重新走生命周期,而是执行复写方法中的方法
launchMode为singleTask的时候,通过Intent启动一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再调用通常情况下我们处理请求数据的onCreate方法,而是调用OnNewIntent方法。


11.下列哪些情况下系统会抛出异常,强制退出?
  • 应用运行时,Main线程进行了耗时操作
  • 应用运行时抛出了OutOfMemoryError
  • 应用运行时抛出了RuntimeException
  • 应用运行时,用户操作过于频繁

AD:产生ANR,程序没有响应,有可能程序会再次响应
BC:程序抛出异常,会强制退出

FC(Force close)原因:
1.Error:OOM,StackOverFlowError
2.RuntimeException


12.Android系统对下列那些对象提供了资源池
  • Message
  • Thread
  • AsyncTask
  • Looper

A:Message提供了消息池,有静态方法Obtain从消息池中取对象
B:Thread默认不提供资源池,除非使用线程池ThreadPool管理
C:AsyncTask是线程池改造的,池里默认提供(核数+1)个线程进行开发操作,最大支持(核数*2+1)个线程,超过后会丢弃其它任务
D:每个Looper创建时创建一个消息队列和线程对象,也不是资源池


13.下列关于IntentService与Service的关系描述错误的是?
  • IntentService是Service的子类
  • IntentService在运行时会启动新的线程来执行任务
  • 启动方式不同
  • 没有区别

解析:IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含Service的生命周期,那么与service不同的是,IntentService在执行onCreate操作的时候,内部开启一个线程,去执行你的耗时操作。
IntentService其实就是一个Service的实现类,启动方式都是startService。


14.下面关于Android中定义style和item的描述正确的是?
  • 都可以减少重复属性设置
  • style可以作用在Activity上
  • Theme类可以继承
  • 一个TextView的style中定义了textColor属性,TextView本身也设置textColor属性,那么TextView本身定义的优先级较高

补充一下:style和theme本质上就是同一个东西,xml格式完全相同,只是我用在activity上我叫他theme,我用在View上我就叫他style,唯一的区别就是style里头控制的各个属性了,某些属性是只有针对Activity才能生效的(例如你View有标题栏嘛有状态栏嘛有导航栏嘛?但是反过来Activity内部却是有一个继承自View的Decorview)。所以style可以作用在activity上,但是theme却不能反过来作用在view上
theme是被final标记的,不能被继承。而且,xml文件中的parent不属于继承。说一下xml文件的解析规则,遇到parent就去parent里面解析,逐个递归,最后解析自己,相同的元素会被后面解析出来的覆盖掉,这也说明了D选项。


15.使用SimpleAdapter作为ListView的适配器,行布局中支持下列哪些组件?
  • TextView
  • FrogressBar
  • CompoundButton
  • ImageView

使用SimpleAdapter作为适配器时,支持三种类型的View,而且是按照如下顺序进行匹配:

  1. 继承Checkable接口
  2. TextView
  3. ImageView

CompoundButton声明如下:
‘public abstract class CompoundButton extends Button implements checkable’
可见他是实现了Checkable接口的按钮,因此也在入选范围

根据SimpleAdapter的源码可知,使用SimpleAdapter作为适配器会按照如下顺序判断View:

  1. 该view是否实现checkable接口
  2. 该view是否是TextView
  3. 该view是否是ImageView

如果以上三种类型都不是,就会抛出IllegalStateExeception


Android专项练习

1.关于Handler的说法正确的是
  • 它实现不同线程间通信的一种机制
  • 它不能在新线程中执行刷新UI的操作
  • 它采用栈的方法来组织任务的
  • 它可以属于一个新的线程

B:只能在UI线程操作UI组件
C:采用队列
D:只能属于创建它的线程


2.我们都知道Handler是线程与Activity通信的桥梁,如果线程处理不当,你的机器会越来越慢,此时可以选择人为的销毁线程来缓解资源,那么线程销毁过程中,会被调用到的方式是?
  • onDestory()
  • onClear()
  • onFinish()
  • onStop()

解析:在Android开发中,经常会用到线程和Timer,如果没有主动关闭它们,当程序结束时,线程并没有被销毁,而是一直在后台运行着,当我们重新启动应用时,又会重新启动一个线程,周而复始,你启动应用次数越多,开启的线程数就越多,你的机器就会变得越慢。还会导致意识不到的错误。

1.线程的销毁
Handler是线程与Activity通信的桥梁,利用handler接收到任务线程,放到任务队列里派对执行
例如:

//调用该任务线程的run() 方法执行任务线程。

Handler updateBarHandler =new handler();
handler.post(Runnable Thread);

//移除handler里的任务线程,调用线程的stop()方法,销毁线程。
handler.removecallbacks(Runnable Thread);

一个简单的例子如下:
import Android.app.Activity;  
import Android.os.Bundle;  
import Android.os.Handler;  
import Android.util.Log;  
public class HandlerThread extends Activity {  
    private static final String TAG = "HandlerThread";  
    private Handler mHandler =  new Handler();  

    private Runnable mRunnable = new Runnable() {  

        public void run() {  
            //为了方便 查看,我们用Log打印出来  
            Log.e(TAG, Thread.currentThread().getName() + "Thread run");          
        }  

    };  
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);   
        //通过Handler启动线程  
        mHandler.post(mRunnable);  
    }  

    @Override 
    protected void onDestroy() {  
        //将线程销毁掉  
        mHandler.removeCallbacks(mRunnable);  
        super.onDestroy();  
    }  
}

2.Timer的销毁
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。当然,你可以通过以下四种方式终止一个timer线程:

  1. 调用timer的clear方法,你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;
  2. 让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目的),这样当程序只有daemon线程的时候,它就会终止运行
  3. 当timer相关的所有task执行完毕后,删除所有此timer对象的引用(置成null),这样timer线程也会终止
  4. 调用System exit方法,使整个程序(所有线程)终止。

3.关于Activity生命周期事件回调函数的说法正确的是
  • onCreate()方法在Activity第一次被创建时调用
  • onStart()方法在Activity开始和用户交互,用户可输入信息时调用
  • onRestart()方法在系统重新启动前一个Activity时调用
  • onStop()方法在Activity对用户不可见时调用

B:onStart()和onStop()方法之间的Activity是可见的,但是并不是可交互或者用户输入信息时侯的回调,只有onResume()之后,用户才可以交互操作Activity。
C:如果是正常回退,这个要看Activity Stack栈顶第二个Activity的状态,可能是onPaused(),如果是onPaused(),则直接回到onResume(),如果是onStop()则需要onRestart()->onStart()->onResume();如果Activity因为Config改变(横竖屏切换),则会重新创建一个Activity或者设置了android:config,则另当别论


4.Broadcast Receiver是一个专注于接收广播通知消息并做出对应处理的组件,下列说法正确的是
  • Broadcast Receiver是对发送出来的广播进行过滤并响应的一类组件
  • 每次广播被接收后会重新创建Broadcast Receiver对象,并在onReceiver方法中执行完成时销毁
  • 如果需要在Broadcast Receiver中执行耗时的操作,可以通过Intent启动Service来完成,并同时绑定Service
  • 定义广播接收器类需要继承Broadcast Receiver基类,并且必须要重写onReceiver()方法。

解析:由于Broadcast Receiver本质上是一种监听器,所以创建Broadcast Receiver的方法也非常简单,只需要创建一个BroadcastReceiver的子类然后重写onReceiver(Context context,Intent intent)方法就行
Broadcast Receiver的生命周期,从对象调用它开始,到onReceiver()方法完成之后结束。另外,每次广播被接收后会重新创建Broadcast Receiver对象,并在onReceiver方法中执行完就销毁,如果Broadcast Receiver的onReceiver方法中不能再10秒内执行完成,Android会出现ANR,所以不要在onReceiver方法中执行耗时的操作
如果需要在Broadcast Receiver中执行耗时操作,可以通过Intent启动Service来完成,但是不能绑定Service。


Android专项练习

1.下面关于android dvm的进程和Linux的进程,应用程序的进程说法正确的是?
  • DVM指dalivk的虚拟机,每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalivk虚拟机实例,而每一个DVM不一定都是在Linux中的一个进程,所以说不是一个概念
  • DVM指dalivk的虚拟机,每一个Android应用系统程序都在它自己的进程中运行,不一定拥有一个独立的Dalivk虚拟机实例,而每一个DVM都是在Linux中的一个进程,所以说是一个概念
  • DVM指dalivk的虚拟机,每一个Android应用系统程序都在它自己的进程中运行,不一定拥有一个独立的Dalivk虚拟机实例,而每一个DVM不一定都是在Linux中的一个进程,所以说不是一个概念
  • DVM指dalivk的虚拟机,每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalivk虚拟机实例,而每一个DVM都是在Linux中的一个进程,所以说是一个概念

解析:Android系统用的就是Linux的内核,DVM可以理解成在Linux上跑的程序,每个应用程序运行时,都会启动一个DVM实例,也就是一个Linux的进程,因此DVM进程和Linux进程实际上是一回事


2.下面属于Android的动画分类的有?(Android3.0之前)
  • Tween
  • Frame
  • Draw
  • Animation

Android的动画分为三种:

  • 帧动画:也就是Frame动画。Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制类似,它的原理是在一定的时间段内切换多张有细微差别的图片从而达到动画的效果。由于是一帧一帧的加载,所以需要较多的图片。从而增大APK的大小,不过Frame动画可以实现一些比较难的效果,例如:等待的环形进度。涉及的Java对象:AnimationDrawable.
  • 补间动画:也就是Tween动画,是操作某一个控件让其展现出旋转,渐变,缩放的一种转换过程,是一种视觉上的变化,不是真正位置上的变化。只能用在View对象上,且功能较为局限。因此,补间动画通常用于执行比较简单的动画。涉及的Java对象有:AlphaAnimation(渐变动画),ScaleAnimation(缩放动画),TranslateAnimation(位移动画),RotateAnimation(旋转动画)
  • 属性动画:Android3.0之后推出的,其机制不再是针对View来设计的,也不限于只能实现移动,缩放,旋转和淡入淡出这几种简单的动画操作,同时也不再只是一种视觉上的动画效果。属性动画实际上是一种在一定时间段内不断修改某个对象的某个属性值的机制。

3.前台进程是Android系统中最重要的进程,在Android系统中包含哪些情况?
  • Activity正在与用户进行交互
  • 进程服务正在执行声明中的回调函数
  • 进程的BroadcastReceiver在执行onReceiver()函数
  • 当一个Activity被部分遮挡时

解析:
1.前台进程:
用户当前操作所必需的进程,如果一个进程满足一下任一条件,即视为前台进程:

  1. 托管用户正在交互的Activity(已调用Activity的onResume()方法)
  2. 托管某个Service,后者绑定到用户正在交互的Activity
  3. 托管正在“前台”运行的Service(服务已调用stateForeground())
  4. 托管正执行一个生命周期回调的Service(onCreate(),onStart()或onDestroy())
  5. 托管正执行其onReceiver()方法的BroadcastReceiver

通常,在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们。此时,设备往往已达到内存分页状态,因此需要终止一些前台进程来确保用户界面正常响应。

2.可见进程:
没有任何前台组件,但仍会影响用户在屏幕上所见内容的进程。如果一个进程满足以下任一条件,即可视为可见进程:

  1. 托管不在前台,但仍对用户可见的Activity(已调用其onPause()方法)。例如,如果前台Activity启动了一个对话框,允许在其后显示上一个Activity,则有可能会发生这种情况。
  2. 托管绑定到可见(或前台)Activity的Service

可见进程被视为是及其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。

3.服务进程:
正在运行已使用startService()方法启动的服务且不属于上述两个更高类别进程的进程。尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如:在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

4.后台进程:
包含目前对用户不可见的Activity进程(已调用Activity的onStop()方法)。这些进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程,可见进程,或服务进程使用。通常会有很多后台进程在运行,因此它们会保存在LRU(最近最少使用)列表中,以确保包含用户最近查看的Activity的进程最后一个被终止。如果某个Activity正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该Activity时,Activity会恢复其所有可见状态。有关保存和恢复状态的信息,请看Activity文档。

5.空进程:
不含任何活动应用组件的进程。保留这种进程的唯一目的是用作缓存,以缩短下次在其中运行组件所需要的启动时间。为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。


4.关于startActivityForResult()方法,如果是A跳转B,B的launchMode属性为singleInstance,A的onActivityResult()回调方法会在什么时候调用呢?
  • B被启动的时候即调用
  • B返回的时候调用
  • 下一次A启动的时候调用
  • 不会被调用

解析:
这道题A和B有争议!我认为是A,答案为B。
启动B的时候立马回调result方法,当launchMode为singleTask或singleInstance时候都这样。只要被启动的activity设置为singleInstance则startActivityForResult不起效。
不同task之间,不能传递数据。


5.Android的自动恢复功能能够完成?
  • 恢复地址簿
  • 修复丢失的文字信息
  • 恢复删除的信息
  • 恢复备份设置和数据来重新安装程序

解析:Android2.2以后的备份服务功能允许用户备份应用数据到云存储中,即当应用执行了工厂服务或转换到一个新的平台上时,如果备份的应用需要重新安装,系统就自动恢复原先备份的数据并重新安装。


6.为满足线程间通信,Android提供了?
  • Handler和Looper
  • Handler
  • Message Queue
  • Looper

解析:
Android提供了Handler和Looper来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(MessageExchange)
Looper:一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)
Handler:你可以构造Handler对象来与Looper沟通,以便Push新消息到MessageQueue里;或者接收Looper从Message Queue所送来的消息
Message Queue(消息队列):用来存放线程放入的消息
线程:UIThread 通常就是main thread,而Android启动程序时会替他建立一个MessageQueue。
这里写图片描述


7.通过Intent传递一些二进制数据的方法有哪些?
  • 使用Serializable接口实现序列化,这是Java常用的方法
  • 实现Parcelable接口,这里Android的部分分类比如Bitmap类就已经实现了,同时Parcel able在Android AIDL中交换数据也很常见
  • 以上都对

解析:
Android中实现序列化有两个选择:

  1. 实现Serializable接口(是JavaSE本身就支持的)
  2. 实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可用于进程间通信(IPC))。

实现Serializable接口非常简单,声明一下就可以;而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。
注:Android中Intent传递对象有两种方法:

  1. Bundle.putSerializable(key,Object)
  2. Bundle.putParcelable(key,Object)

当然这些Object是有一定条件的,前者实现了Serializable接口,而后者实现了Parcelable接口。
Serializable本身就是Java特有的序列化接口。而Parcelable是Android才有的,之所以Android还要弄出Parcelable而不直接用Serializable,就是因为Parcelable更加高效,但比起Serializable在写法上要复杂一些。


8.在Android应用程序开发中,可以通过()获取屏幕的属性,从而取得屏幕的高度和宽度
  • getMetrics
  • getDisplay
  • getScreen
  • getWindows

解析:
获取屏幕密度 :getScreen
获取设备屏幕大小:getDisplay
获取屏幕属性,从而取得屏幕的高度和宽度:getMetrics
获取window对象:getWindows


9.Android DVM的进程和Linux的进程,应用程序的进程是否为同一概念
  • 不是

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

Dalvik是Google公司自己设计用于Android平台的Java虚拟机,每一个Dalvik应用作为一个独立的Linux进程执行。独立的进程可以防止在虚拟机奔溃的时候所有程序都被关闭。

Dalvik和Java运行环境的区别:

  1. Dalvik主要是完成对象生命周期管理。堆栈管理,线程管理,安全和异常管理,以及垃圾回收等重要功能。
  2. Dalvik负责进程隔离和线程管理,每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
  3. 不同于Java虚拟机运行Java字节码,Dalvik虚拟机运行的是其专有的文件格式DEX
  4. dex文件格式可以减少整体文件尺寸,提高I/O操作的类查找速度。
  5. odex是为了在运行过程中进一步提高性能,对dex文件的进一步优化
  6. 所有的Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
  7. 有一个特殊的虚拟机进程Zygote,他是虚拟机实例的孵化器。它在系统启动的时候就会产生,它会完成虚拟机的初始化,库的加载,预制类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的数据提供给系统。对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域。

10.Android中MVC模式C层指的是?
  • Activity
  • Services
  • Content
  • Intent

解析:
Android中界面部分也采用了当前比较流行的MVC框架,在Android中:

  1. 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如果你对Android了解的比较多了的话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是Android提供了它们之间非常方便的通信方式
  2. 控制层(Controller):Android的控制层的重任通常落在了众多的Activity的肩上,这句话也就暗含了不要再Activity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
  3. 模型层(Model):对数据库的操作,对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在该层的。就是应用程序中二进制的数据
    在Android SDK中的数据绑定,也都是采用了与MVC框架类似的方法来显示数据。在控制层上将数据按照视图模型的要求(也就是Android SDK中的Adapter)封装就可以直接在视图模型上显示了,从而实现了数据绑定。比如显示Cursor中所有数据的ListActivity,其视图就是一个ListView,将数据封装为ListAdaoter,并传递给ListView,数据就在ListView中实现。

1.以下关于Toast说法正确的是()
  • Toast能编辑
  • Toast没有焦点
  • Toast可以获得用户输入
  • Toast只能持续一段时间

解析:
如果从用户角度来说,是不能编辑的。


2.Broadcast Receiver是一个专注于接收广播通知,并做出对应处理的组件,下列说法正确的是()
  • Broadcast Receiver是对发送出来的广播进行过滤接收并响应的一类组件
  • 每次广播被接收后会重新创建Broadcast Receiver对象,并在onReceiver方法中执行完成销毁
  • 如果需要在Broadcast Receiver中执行耗时的操作,可以通过Intent启动Service来完成,并同时绑定Service
  • 定义广播接收器类需要继承Broadcast Receiver基类,并且必须要重写onReceive()方法。

解析:
Broadcast Receiver本质上是一种监听器,所以创建Broadcast Receiver的方法也非常简单,只需要创建一个Broadcast Receiver的子类然后重写onReceiver(Context context,Intent intent)方法即可
Broadcast Receiver的生命周期,从对象调用它开始,到onReceiver方法执行完成之后结束,另外,每次广播被接收后会重新创建Broadcast Receiver对象,并在onReceiver()方法中执行完就销毁,如果Broadcast Receiver的onReceiver方法中不能在10s内执行完成,Android就会出现ANR异常,所以不要在Broadcast Receiver的onReceiver方法中执行耗时操作。
如果要在Broadcast Receiver中执行耗时操作,可以通过Intent启动Service来完成,但不能绑定Sercvice。


3.使用AIDL完成远程service方法调用下列说法不正确的是
  • aidl对应的接口名称不能与aidl文件名相同
  • aidl的文件的内容类似Java代码
  • 创建一个Service(服务),在服务的onBinder(intent)方法中返回实现了aidl接口的对象
  • aidl对应的接口的方法前面不能加访问权限修饰符

解析:编写aidl文件时,需要注意以下几点:

  1. 接口名和aidl文件名相同
  2. 接口和方法不用加访问权限修饰符Public,private,protected的等,也不能用final,static
  3. aidl默认支持的类型包括Java基本类型和(String,List,Map,CharSquence),使用这些类型时不需要import声明,对于List和Map中的元素类型必须aidl支持的类型,如果使用自定义类型作为参数或返回值,自定义类型必须实现Paracelable接口
  4. 自定义类型和Aidl生成的其他接口类型在aidl描述文件中,应该显示import,即便在该类和定义的包在用一个包中
  5. 在aidl文件中所有非Java基本类型参数必须加上in,out,inou标记,以指明参数是输入参数,输出参数还是输入输出参数
  6. Java原始类型默认的标记为in,不能为其他标记

AIDL Android Interface Definition Language,即Android接口定义语言
Android使用AIDL提供公开服务接口,使得不同进程间可以相互通信


4.Android系统对下列那些对象提供了资源池
  • Message
  • Thread
  • AsyncTask
  • Looper

解析:
A:Message提供了消息池,有静态方法Obtain从消息池中取对象
B:Thread默认不提供资源池,除非使用线程池Thread Pool管理
C:AsyncThread是线程池改造的,池里默认提供(核数+1)个线程进行并发操作,最大支持(核数*2+1)个线程,超过后会丢弃其它任务
D:Looper,每个Looper创建时创建一个消息队列和线程对象,也不是资源池。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值