Android常见面试笔试题目

Android常见面试笔试题目html

一、在多线程编程这块,咱们常常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢?java

答:能够处理消息循环的线程,他是一个拥有Looper的线程,能够处理消息循环。与其说Handler和一个线程绑定,不如说Handler是和Looper一一对应的。最后须要说明的是,在UI线程(主线程)中:   mHandler=new Handler(); linux

mHandler.post(new Runnable(){android

  void run(){c++

  //执行代码...}web

  });面试

  这个线程实际上是在UI线程以内运行的,并无新建线程。sql

  常见的新建线程的方法是:数据库

  Thread thread = new Thread();编程

  thread.start();

  HandlerThread thread = newHandlerThread("string");

  thread.start();

二、如何设定应用程序获取system权限;如何获取以下:

解释链接:http://blog.csdn.net/superkris/article/details/7709504

 第一个方法简单点,不过须要在Android系统源码的环境下用make来编译:

       1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android.uid.system"这个属性。

       2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行

       3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。

       第二个方法是直接把eclipse编出来的apk用系统的签名文件签名

       1. 加入android.uid.system"这个属性。

       2. 使用eclipse编译出apk文件。

       3. 使用目标系统的platform密钥来从新给apk文件签名。首先找到密钥文件,在我ndroid源码目录中的位置是"build/target/product/security",下面的platform.pk8和platform.x509.pem两个文件。而后用为java -jarsignapk.jar  platform.x509.pem platform.pk8 input.apk output.apk"。

       加入android.能够配置成运行在同一个进程中。那么把程序的android.只是加入能够放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE :=platform其实就是用这两个key来签名。

       这也有一个问题,就是这样生成的程序只有在原始的能够用,因能够拿到platform.pk8和platform.x509.pem两个文件。要是别家公司作的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package... has no signatures that match those in shared user uid.system",这样也是保护了系统的安全。

三、谈谈Android系统中,每个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不一样的进程中,Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通讯(IPC)机制, 可是,Android系 统的Binder机制中,由一系统组件组成,分别是Client、Server、Service Manager和Binder驱动程序,其中Client、Server和Service Manager运行在用户空间,Binder驱动程序运行内核空间。Binder就是一种把这四个组件粘合在一块儿的粘结剂了,其中,核心组件即是 Binder驱动程序了,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和ServiceManager提供的基础设施上,进行 Client-Server之间的通讯;

   1. Client、Server和Service Manager实如今用户空间中,Binder驱动程序实如今内核空间中

  2. Binder驱动程序和Service Manager在驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager经过open和ioctl文件操做函数与Binder驱动程序进行通讯

  4. Client和Server之间的进程间通讯经过Binder驱动程序间接实现

   5. Service Manager是一个守护进程,用来管理Server,并向Client提供查询Server接口的能力

四、apk安装卸载的原理

答:http://blog.csdn.net/lizhiguo0532/article/details/7077432

     http://www.itivy.com/android-apk-setup-method-and-principles.html

APK安装能够经过如下四种方式:
1. 系统应用安装,开机时完成系统应用的检查,没安装就安装,安装就跳过,无安装界面。
2. 网络下载应用安装,经过market应用完成,无安装界面。
3. ADB工具安装,无安装界面
4. 经过SD卡来安装apk,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。

应用安装涉及到以下几个目录:
system/app     系统自带的应用程序,没法删除
data/app     用户程序安装的目录,有删除权限
data/data     存放应用程序的数据
Data/dalvik-cache   将apk中的dex文件安装到dalvik-cache目录下
(dex文件是dalvik虚拟机的可执行文件,其大小约卸载过程:删除安装过程当中在上述三个目录下建立的文件及目录。

五、如何作适配

1)2) 偏移量d的设置值得一提的是:

 

    <dimen name=“bitmap_common_topoffset”>40dp</dimen>

    <dimen name=“bitmap_common_bottomoffset”>-14dp</dimen>

这里的为它是一个负值

3)各大手机厂商对于 好比:

  (1)系统源代码中链接music服务的aidl文件所在包名:com.android.music 

  (2)LG则可能将该aidl文件修改所在的包(例如修改android.music.player),而且修改其中的文件内容(增长一个方法,或者减小几个方法,或者修改方法名称)那么咱们的应用要想在LG的手机上发布,那么咱们就必须改变所要链接的aidl文件,必须跟LG厂商修改的彻底一致。

 

六、是否进行过apk反编译,如何防止反编译

反编译:

     dex2jar + jdgui

·       apktool

防止反编译:

·       代码加密

这方式,也只能想一想,一旦你本身加密了,代码混淆

这种方式,其实我不大愿意将他归类于防止反编译,从为,
妨碍对反编译代码的阅读、观看和理解

的配置来实现。

具体的实现网上针对这部分的解释已经太多,因此这里不详细介绍了。

·       动态加载类

这种方式的启发是根据web端来的。Web端你要防止,那就不发布呗。

因此咱们用NDK开发核心代码

从上面已经能知道,C/C++等编译型语言的反汇编难度。因此咱们能够经过 #include直接编译到库里(固然内存可能就大了),这种方式能够本身考虑。

 

七、又称“补间动画”、“中间动画”,最先接触Tween类是在学习Flash时候,使用ActionScript作动画的时候,使用过类Tween。

 

        Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间, 位置 ,等等。可是Tween动画的缺点是它只能设置起始点与结束点的两帧,中间过程所有由系统帮咱们完成。因此在帧数比较多的游戏开发中是不太会用到它的。
       Tween一共提供了4中动画的效果

       Scale:缩放动画
       Rotate:旋转动画
       Translate:移动动画
       Alpha::透明渐变更画

Frame动画

       又称帧动画,主要显示方式是<animation-list>android:oneshot="false"这是一个很是重要的属性,默认android:drawable="@drawable/a"表示这一帧用的图片android:duration="100" 表示这一帧持续100毫秒,能够根据这个值来调节动画播放的速度。

 

 八、AIDL全称,如何工做,可处理那些数据

答:AIDL的英文全称是为RemoteService.stub的内部类,该内部类中含有aidl文件接口的get方法。
说明一:aidl文件的位置不固定,能够任意
而后定义本身的MyService类,在MyService类中自定义一个内部类去继承RemoteService.stub这个内部类,实现get方法。在onBind方法中返回这个内部类的对象,系统会自动将这个对象封装成IBinder对象,传递给他的调用者。
其次须要在AndroidManifest.xml文件中配置MyService类,代码以下:
<!-- 注册服务 --> 
<service android:name=".MyService">
  <intent-filter>
   <!--  指定调用AIDL服务的ID  -->
      <actionandroid:name="net.blogjava.mobile.aidlservice.RemoteService"/>
   </intent-filter>
</service>
为何要指定调用AIDL服务的ID,就是要告诉外界MyService这个类可以被别的进程访问,只要别的进程知道这个ID,正是有了这个ID,B工程才能找到A工程实现通讯。
说明:AIDL并不须要权限
B工程:
      首先咱们要将A工程中生成的RemoteService.java文件拷贝到B工程中,在bindService方法中绑定aidl服务
      绑定AIDL服务就是将RemoteService的ID做为intent的action参数。
      说明:若是咱们单独将RemoteService.aidl文件放在一个包里,那个在咱们将gen目录下的该包拷贝到B工程中。若是咱们将 RemoteService.aidl文件和咱们的其余类存放在一块儿,那么咱们在B工程中就要创建相应的包,以保证RmoteService.java文 件的报名正确,咱们不能修改RemoteService.java文件
         bindService(newInten("net.blogjava.mobile.aidlservice.RemoteService"),serviceConnection,Context.BIND_AUTO_CREATE);
      ServiceConnection的onServiceConnected(ComponentName name, IBinderservice)方法中的service参数就是A工程中MyService类中继承了RemoteService.stub类的内部类的 对象。

九、可使用一静态类来优化处理getview的过程/

3.Bitmap对象不使用时采用recycle()释放内存

4.activity中的对象的生命周期大于activity
调试方法: DDMS==> HEAPSZIE==>dataobject==>[TotalSize]

 

 

十、什么状况会致使Force Close ?如何避免?可否捕获致使其的异常?
答:通常像空指针啊,为standard,singleTop,singleTask,singleInstance。若是要使用这四种启动模式,必须在manifest文件中<activity>标签中的launchMode属性中配置,如:

 

<activity android:name=".app.InterstitialMessageActivity"  
          android:label="@string/interstitial_label"  
          android:theme="@style/Theme.Dialog"  
          android:launchMode="singleTask"  
</activity> 

standard

标准启动模式,也是activity的默认启动模式。在这种模式下启动的activity能够存在多个activity的实例,每一个实例都会处理一个Intent对象。若是Activity A的启动模式为A-->A。

singleTop

若是一个以singleTop模式启动的activity的实例已经存在于任务桟的桟顶,那么再启动这个Activity时,不会建立新的实例,而是重用位于栈顶的那个实例,而且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中。举例来讲,若是A的启动模式为和standard模式相同,也会建立多个实例。

singleTask

谷歌的官方文档上称,若是一个activity的启动模式为singleTask的activity并不会老是开启一个新的任务。详情请参考 解开Android应用程序组件Activity"singleTask"之谜,在本文后面也会经过示例来进行验证。

singleInstance

老是在新的任务中开启,而且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其余activity会 自动运行于另外一个任务中。当再次启动该activity的实例时,会重用已存在的任务和实例。而且会调用这个实例的onNewIntent()方法,将 Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。

 

十二、NDK是什么

NDK:NativeDevelopment Kit

 AndroidNDK是一个让开发人员在Android应用运行在Dalvik虚拟机中。NDK容许开发人员使用本地代码语言(例如C和C++)实现应用的部分功能。这样以代码重用的形式可以给某类应用提供方便,并且在某些状况下能提升运行速度(感谢老婆的帮助)。

 

1三、请解释下android受权)
    文件系统 linux 内核受权

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

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

三、设置Activity的Android应用android源代码的packages/apps/目录下,添加Android.mk文件 
2 在应用程序的AndroidManifest.xml中的manifest节点中加入android.uid.system"这个属性。 
3 修改Android.mk文件,加入LOCAL_CERTIFICATE:= platform这一行 
4 使用mm命令来编译,生成的apk就有同system同样的权限了。 
5 在android根目录下用make snod从新生成system.img 
6 启动emulator运行下应用看看是否好了。 

 

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

Android工程中的res aw目录中。全部在res aw目录中的文件不会被压缩,这样能够将dictionary.db文件复制到res aw目录中
17.如何将打开res aw目录中的数据库文件?
解答:在Android SDK中能够接受对应的广播。

 

动态注册的时候,若是不执行unregisterReceiver();方法取消注册,跟静态是同样的。可是若是执行该方法,当执行过之后,就不能接受广播了。

20、在Android NDK
2)在ndk项目中JNI接口的设计
3)使用C/C++实现本地方法
4)JNI生成动态连接库.so文件
5)将动态连接库复制到java工程,在java工程中调用,运行java工程便可
2一、简述Android应用程序结构是:
Linux Kernel(Linux内核)、

Libraries(系统运行库或者是c/c++核心库)、

Application Framework(开发框架包)、

Applications (核心应用程序)
2二、请继承SQLiteOpenHelper实现:

1).建立一个版本为1的“diaryOpenHelper.db”的数据库,
2).同时建立一个 “diary” 表(包含一个_id主键并自增加,topic字符型100
长度, content字符型1000长度)
3).在数据库版本变化时请删除diary表,并从新建立出diary表。

publicclass DBHelper  extendsSQLiteOpenHelper{

public final static String DATABASENAME ="diaryOpenHelper.db";
public final static int DATABASEVERSION =1;

//建立数据库
public DBHelper(Context context,Stringname,CursorFactory factory,int version)
{
super(context, DATABASENAME, factory, DATABASEVERSION);
}
//建立表等机构性文件
public void onCreate(SQLiteDatabase db)
{
String sql ="create tablediary"+
"("+
"_idinteger primary key autoincrement,"+
"topicvarchar(100),"+
"contentvarchar(1000)"+
")";
db.execSQL(sql);
}
//若数据库版本有更新,则调用此方法
public void onUpgrade(SQLiteDatabasedb,int oldVersion,int newVersion)
{

String sql = "drop table ifexists diary";
db.execSQL(sql);
this.onCreate(db);
}
}

2三、页面上现有ProgressBar控件progressBar,请用书写线程以10秒的的时间完成其进度显示工做。
publicclass ProgressBarStu extends Activity {

private ProgressBar progressBar = null;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
//从这到下是关键
progressBar = (ProgressBar)findViewById(R.id.progressBar);

Thread thread = new Thread(newRunnable() {

@Override
public void run() {
int progressBarMax =progressBar.getMax();
try {
while(progressBarMax!=progressBar.getProgress())
{

intstepProgress = progressBarMax/10;
intcurrentprogress = progressBar.getProgress();
progressBar.setProgress(currentprogress+stepProgress);
Thread.sleep(1000);
}

} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}

}
});

thread.start();

//关键结束
}

}
2四、请描述下Activity的生命周期。

必调用的三个方法:onCreate() --<onStart() --< onResume(),用AAA表示
(1)父Activity启动子Activity,子Actvity退出,父Activity调用顺序以下
AAA --< onResume () --< onPause() --< onStop() --<onRestart()--< onStart(),onResume() …
(2)用户点击Home,Actvity调用顺序以下
AAA --< onResume () --< onPause() --< onStop() -- Maybe--<onDestroy() – Maybe
(3)调用finish(), Activity调用顺序以下
AAA --< onPause() --< onStop() --< onDestroy()
(4)在Activity上显示dialog,Activity调用顺序以下
AAA
(5)在父Activity上显示透明的或非全屏的activity,Activity调用顺序以下
AAA --< onResume () --< onPause()
(6)设备进入睡眠状态,Activity调用顺序以下
AAA --< onFreeze() --< onPause()
2五、若是后台的Activity因为某缘由被系统回收了,如何在被系统回收以前保存当前状态?

在oncreate中写以下取得保存的状态:

1.  if (savedInstanceState != null  

2.              && savedInstanceState.getInt("currentposition") != 0) {  

3.    

4.          videoView.seekTo(savedInstanceState.getInt("currentposition"));  

5.      }  

重写这个方法保存状态

6.  protected void onSaveInstanceState(Bundle outState) {  

7.      // TODO Auto-generated method stub  

8.      outState.putInt("currentposition", videoView.getCurrentPosition());  

9.      Log.v("tag", "onSaveInstanceState");  

10.     super.onSaveInstanceState(outState);  

11. }   


当你的程序中某一个Activity A在运行时,主动或被动地运行另外一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成之后又会来找A,这个时候就有两种状况:一是A被回收,二是A没有被回收,被回 收的A就要从新调用onCreate()方法,不一样于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被 收回的就直接执行onResume(),跳过onCreate()了。
2六、如何将一个Activity设置成窗口的样式。

在AndroidManifest.xml 中定义Activity的地方一句话android:style/Theme.Dialog"或android:style/Theme.Translucent"就变成半透明的
2七、如何退出Activity?如何安全退出已调用多个Activity的Application?

对于单一Activity的应用来讲,退出很简单,直接finish()便可。
固然,也能够理解能够经过如下方法完成:
post(Runnable):Runnable在handler绑定的线程上执行,也就是说不建立新线程。
postAtTime(Runnable,long):
postDelayed(Runnable,long):
sendEmptyMessage(int):
sendMessage(Message):
sendMessageAtTime(Message,long):
sendMessageDelayed(Message,long):
post这个动做让你把Runnable对象排入MessageQueue,MessageQueue受到这些消息的时候执行他们,固然以必定的排序。 sendMessage这个动做容许你把Message对象排成队列,这些Message对象包含一些信息,Handler的 hanlerMessage(Message)会处理这些Message.固然,handlerMessage(Message)必须由Handler的 子类来重写。这是编程人员须要做的事。

当posting或者sending到一个Hanler时,你为:当MessageQueue准备好就处理,定义一个延迟时间,定义一个精确的时间去处理。后二者容许你实现timeout,tick,和基于时间的行能够创 建本身的线程,并经过一个Handler和主线程进行通讯。这和以前同样,经过post和sendmessage来完成,差异在于在哪个线程中执行这么 方法。在恰当的时候,给定的Runnable和Message将在Handler的MessageQueue中被Scheduled。


Message简介:
Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域,这能够经过Looper.myQueue()从当前线程中获取MessageQueue。


Looper简介:
Looper类被用来执行一个线程中的message循环。默认状况,没有一个消息循环关联到线程。在线程中调用prepare()建立一个Looper,而后用loop()来处理messages,直到循环终止。

大多数和message loop的交互是经过Handler。

下面是一个典型的带有Looper的线程实现。
  class LooperThread extends Thread {
      public Handler mHandler;
     
      public void run() {
          Looper.prepare();
         
          mHandler = new Handler() {
              publicvoidhandleMessage(Message msg) {
                  // processincomingmessages here
              }
          };
         
          Looper.loop();
      }
  }
30、系统上安装了多种浏览器,可否指定某浏览器访问指定页面?请说明起因。

经过直接发送Uri把参数带过去,或者经过manifest里的intentfilter里的data属性

3一、什么是ANR如何避免它?

ANR:ApplicationNotResponding,五秒

在Android就会显示ANR对话框了:

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

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

为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intentbroadcast)。

所以,任何运行在主线程中的方法,都要尽量的只作少许的工做。特别是活动生命周期中的重要方法如onCreate()和 onResume()等更应如此。潜在的比较耗时的操做,如访问网络和数据库;或者是开销很大的计算,好比改变位图的大小,须要在一个单独的子线程中完成 (或者是使用异步请求,如数据库操做)。但这并不意味着你的主线程须要进入阻塞状态已等待子线程结束 -- 也不须要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程能够参看Snake的例子,这种方法与之前咱们所接触的有所不一样)。使用这种方法涉及你的应用程序,可以保证你的程序对输入保持良好的响应,从而避免由于他们都面临着一样的超时问题。

更多
相关文章
相关标签/搜索