Android面试中常问的问题

1.在android中,请简述jni的调用过程。
1)安装和下载Cygwin,下载 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  (核心应用程序)
3.请继承SQLiteOpenHelper实现:
1)创建一个版本为1的“diaryOpenHelper.db”的数据库,
2)同时创建一个 “diary” 表(包含一个_id主键并自增长,topic字符型100长度, content字符型1000长度)    
3)在数据库版本变化时请删除diary表,并重新创建出diary表。
   
public class DBHelper extends SQLiteOpenHelper{
 
public final static String DATABASENAME ="diaryOpenHelper.db";
public final static int DATABASEVERSION =1;
 
//创建数据库
public DBHelper(Context context,Stringname,CursorFactory factory,int version)
{
super(context, name, factory,version);
}
//创建表等机构性文件
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 if exists diary";
db.execSQL(sql);
this.onCreate(db);
}
}
4.页面上现有控件progressBar,请用书写线程以10秒的的时间完成其进度显示工作。
   
public class 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())
{
int stepProgress = progressBarMax/10;
int currentprogress = progressBar.getProgress();
progressBar.setProgress(currentprogress+stepProgress);
Thread.sleep(1000);
}
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
});
thread.start();
 
}
}
5. 如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?       onSaveInstanceState()
      当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()。B完成以后又会来找A,这个时候就有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。 
6.  如何将一个Activity设置成窗口的样式。      
在AndroidManifest.xml 中定义Activity的地方一句话android:theme="@android:style/Theme.Dialog"或 android:theme="@android:style/Theme.Translucent"就变成半透明的
7.  如何退出Activity?如何安全退出已调用多个Activity的Application?
对于单一Activity的应用来说,退出很简单,直接finish()即可。
当然,也可以用killProcess()和System.exit()这样的方法。
但是,对于多Activity的应用来说,在打开多个Activity后,如果想在最后打开的Activity直接退出,上边的方法都是没有用的,因为上边的方法都是结束一个Activity而已。
那么,有没有办法直接退出整个应用呢?
现提供几个方法,供参考:
7.1  抛异常强制退出:

该方法通过抛异常,使程序ForceClose。
验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。
7.2  记录打开的Activity:
每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
7.3  发送特定广播:
在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
7.4  递归退出
在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。
8.请介绍下Android的数据存储方式。
8.1  SharedPreferences方式
存储路径:(data/data/packagename/shares_prefs),轻量级存储,以键值对的形式存储在xml中,一般用来保存应用中的设置属性
8.2  文件存储方式
SD卡存储多媒体文件,文件缓存
8.3  SQLite数据库方式
存储路径:(data/data/packagename/databases),一种嵌入式数据库,支持sql语言,存储大量结构性数据
8.4  内容提供器(Content provider)方式
进程(应用程序)间数据共享,数据源可以是sqlite,也可以是xml,相关类:ContentResolver(内容解析器),ContentObserver(数据观察者)
8.5  网络存储方式
天气数据的xml,json格式等等,通过HttpUrlConnection,HttpClient,或者SOAP协议获取数据
9.如何启用Service,如何停用Service。
Android中的service类似于windows中的service,service一般没有用户操作界面,它运行于系统中不容易被用户发觉, 可以使用它开发如监控之类的程序。
9.1 步骤
第一步:继承Service类
public class SMSService extends Service { }
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".DemoService" />
9.2 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()方法。
9.3 Service的生命周期
Service 的生命周期 :onCreate,onStartCommand,onDestroy,onBind 和 onUnbind 。
通常有两种方式启动一个 Service, 它们对 Service 生命周期的影响是不一样的。
1) 通过 context.startService(),onCreate-->onStartCommand-->onDestroy
Service 会经历 onCreate 到 onStartCommand ,然后处于运行状态, stopService 的时候调用 onDestroy 方法。
如果是调用者自己直接退出而没有调用 stopService 的话, Service 会一直在后台运行。
如果 Service 已经启动了,当我们再次启动 Service 时,不会在执行 onCreate() 方法,而是直接执行 onStartCommand() 方法。
2) 通过 context.bindService(),onCreate--> onBind--->onUnbind-->onDestroy
Service 会运行 onCreate ,然后是调用 onBind ,这个时候调用者和 Service 绑定在一起。调用者退出了, Srevice 就会调用 onUnbind->onDestroyed 方法。
所谓绑定在一起就共存亡了。调用者也可以通过调用 unbindService 方法来停止服务,这时候 Srevice 就会调用 onUnbind->onDestroyed 方法。

备注:
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);//解除绑定

注 :onStartCommand() 有四种返回值 :
· START_STICKY :如果 service 进程被 kill 掉,保留 service 的状态为开始状态,但不保留递送的 intent 对象。随后系统会尝试重新创建 service ,由于服务状态为开始状态,所以创建服务后一定会调用 onStartCommand(Intent,int,int) 方法。如果在此期间没有任何启动命令被传递到 service ,那么参数 Intent 将为 null
· START_NOT_STICKY 非粘性的 。使用这个返回值时,如果在执行完 onStartCommand 后,服务被异常 kill 掉,系统将会把它置为 started 状态,系统不会自动重启该服务,直到 startService(Intent intent) 方法再次被调用 ;
· START_REDELIVER_INTENT :重传 Intent 。使用这个返回值时,如果在执行完 onStartCommand 后,服务被异常 kill 掉,系统会自动重启该服务,并将 Intent 的值传入。
· START_STICKY_COMPATIBILITY START_STICKY 的兼容版本,但不保证服务被 kill 后一定能重启。
10.Service是否运行在主线程,Service与Activity是否运行在同一个线程?
Service 与 Activity 与 BroadcastReceiver 同样都运行在 UI 主线程 , 如果有耗时操作都会引发 ANR 问题。

11.IntentService的用法
Service的子类,主要用来解决在Service中处理耗时操作.
IntentService
使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程

12.广播的发送方式有哪些
sendBroadcast(),sendOrderedBroadcast()和sendStickyBroadcast()三种

·sendBroadcast()这个方法的广播是能够发送给所有广播接收者,按照注册的先后顺序,如果你这个时候设置了广播接收者的优先级,优先级如果恰好与注册顺序相同,则不会有任何问题,如果顺序不一样,会出leaked IntentReceiver这样的异常,并且在前面的广播接收者不能调用abortBroadcast()方法将其终止,如果调用会出BroadcastReceiver trying to return result during a non-ordered broadcast的异常,当然,先接收到广播的receiver可以修改广播数据。

·sendOrderedBroadcast()方法顾名思义就是priority的属性能起作用,并且在队列前面的receiver可以随时终止广播的发送。还有这个api能指定finalreceiver,这个receiver是最后一个接收广播时间的receiver,并且一定会接收到广播事件,是不能被前面的receiver拦截的。实际做实验的情况是这样的,假设我有3receiver依序排列,并且sendOrderedBroadcast()方法指定了一个finalReceiver,那么intent传递给这4Receiver的顺序为Receiver1-->finalReceiver-->Receiver2-->finalReceiver-->Receiver3-->finalReceiver。这个特性可以用来统计系统中能监听某种广播的Receiver的数目。

·sendStickyBroadcast()字面意思是发送粘性的广播,使用这个api需要权限android.Manifest.permission.BROADCAST_STICKY,粘性广播的特点是Intent会一直保留到广播事件结束,而这种广播也没有所谓的10秒限制,10秒限制是指普通的广播如果onReceive方法执行时间太长,超过10秒的时候系统会将这个广播置为可以干掉的candidate,一旦系统资源不够的时候,就会干掉这个广播而让它不执行。


: ( 下面是广播接收者的生命周期以及一些细节部分:
1.
广播接收者的生命周期是非常短暂的,在接收到广播的时候创建, onReceive() 方法结束之后销毁
2.
广播接收者中不要做一些耗时的工作,否则会弹出 Application No Response 错误对话框
3.
最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
4.
耗时的较长的工作最好放在服务中完成 )
13.注册广播有几种方式,这些方式有何优缺点?
Android广播机制(两种注册方法) 
在android下,要想接受广播信息,那么这个广播接收器就得我们自己来实现了,我们可以继承BroadcastReceiver,就可以有一个广播接受器了。有个接受器还不够,我们还得重写BroadcastReceiver里面的onReceiver方法,当来广播的时候我们要干什么,这就要我们自 己来实现,不过我们可以搞一个信息防火墙。具体的代码:
  
public class SmsBroadCastReceiverextends BroadcastReceiver
{
 
@Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
Object[] object = (Object[])bundle.get("pdus");
SmsMessage sms[]=new SmsMessage[object.length];
for(int i=0;i<object.length;i++)
{
sms[0] =SmsMessage.createFromPdu((byte[])object);
Toast.makeText(context, "来自"+sms.getDisplayOriginatingAddress()+"的消息是:"+sms.getDisplayMessageBody(),Toast.LENGTH_SHORT).show();
}
//终止广播,在这里我们可以稍微处理,根据用户输入的号码可以实现短信防火墙。
abortBroadcast();
}
}
当实现了广播接收器,还要设置广播接收器接收广播信息的类型,这里是信息:android.provider.Telephony.SMS_RECEIVED
我们就可以把广播接收器注册到系统里面,可以让系统知道我们有个广播接收器。这里有两种,一种是代码动态注册:
//生成广播处理  
smsBroadCastReceiver = newSmsBroadCastReceiver();   
//实例化过滤器并设置要过滤的广播  
IntentFilter intentFilter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED");  
//注册广播   
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,intentFilter);  
一种是在AndroidManifest.xml中配置广播
  
<?xml version="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="spl.broadCastReceiver"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"android:label="@string/app_name">
<activity android:name=".BroadCastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--广播注册-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filterandroid:priority="20">
<actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
<!-- 权限申请 -->
<uses-permissionandroid:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>
两种注册类型的区别是:
    1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
    2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

14.请解释下在单线程模型中Message、Handler、MessageQueue、Looper之间的关系。
Handler简介:
一个Handler允许你发送和处理Message和Runable对象,这些对象和一个线程的MessageQueue相关联。每一个线程实例和一个单独的线程以及该线程的MessageQueue相关联。当你创建一个新的Handler时,它就和创建它的线程绑定在一起了。这里,线程我们也可以理解为线程的MessageQueue。从这一点上来看,Handler把Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们。
Handler有两个主要的用途:
(1)确定在将来的某个时间点执行一个或者一些Message和Runnable对象。
(2)在其他线程(不是Handler绑定线程)中排入一些要执行的动作。

Scheduling Message,即(1),可以通过以下方法完成:
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,和基于时间的行为。
当你的应用创建一个新的进程时,主线程(也就是UI线程)自带一个MessageQueue,这个MessageQueue管理顶层的应用对象(像activities,broadcast receivers等)和主线程创建的窗体。你可以创建自己的线程,并通过一个Handler和主线程进行通信。这和之前一样,通过post和sendmessage来完成,差别在于在哪一个线程中执行这么方法。在恰当的时候,给定的Runnable和Message将在Handler的MessageQueue中被Scheduled。

Message简介:
Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域,这可以让你在大多数情况下不用作分配的动作。
尽管Message的构造函数是public的,但是获取Message实例的最好方法是调用Message.obtain(),或者Handler.obtainMessage()方法,这些方法会从回收对象池中获取一个。

MessageQueue简介:
这是一个包含message列表的底层类。Looper负责分发这些message。Messages并不是直接加到一个MessageQueue中,而是通过MessageQueue.IdleHandler关联到Looper。
你可以通过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() {
public voidhandleMessage(Message msg) {
// process incomingmessages here
}
};
 
Looper.loop();
}
}
15.什么是ANR如何避免它?(Android线程间的通信方式?)
答:ANR:ApplicationNotResponding(应用程序无响应).当出现下列情况时,Android就会显示ANR对话框了:对输入事件(如按键、触摸屏事件)的响应超过5秒意向接受器(intentReceiver)超过10秒钟仍未执行完毕Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。
解决方案有两种:
1.AsyncTask异步任务中,doInBackground()和onPostExecute(Result)两个方法非常重要
doInBackground()这个方法运行在后台线程中,主要负责执行那些很耗时的操作,如移动护理系统中的网络连接、解析XML等操作。该方法必须重载。
onPostExecute(Result)这个方法也运行于UI线程,在doInBackground(Params…)方法执行后调用,该方法用于处理后台任务执行后返回的结果。
2.子thread+handler
16.AsyncTask的主要方法有哪些?如何启动和停止AsyncTask?如何在AsyncTask中更新UI

答: AsyncTask的主要方法有doInBackGround()运行在后台子线程,执行耗时操作
onPostExcute()运行在UI主线程,用于执行刷新UI的代码
启动通过execute()方法
停止通过cancel(boolean flag)方法取消执行,传入参数ture表示如果调用方法时异步任务正在执行则打断执行并取消,如果传false表示执行完毕再取消
刷新UI的代码一般卸载onPostExcute()方法中
17.掌握Android项目目录结构
1.src目录:src(即Source Code),src目录用来存放应用程序中所有的源代码,代码的源文件一般存放在该目录下的相应的包下。
2.gen目录:gen目录,该目录下一般只有一个文件,即R文件。该文件夹下面有个R.java文件,R.java是在建立项目时自动生成的,定义该项目所有资源的索引。
3.Android4.1目录:该文件夹下包含android.jar文件,这是一个Java归档文件,其中包含构建应用程序所需的所有的Android SDK库(如Views、Controls)和APIs。
通过android.jar将自己的应用程序绑定到Android SDK和Android Emulator,这允许你使用所有Android的库和包,且使你的应用程序在适当的环境中调试。
4.assets目录:该目录存放应用程序中使用的外部资源文件,如声音视频等,在Android程序中可以通过输入/输出流对该目录中的文件进行读写。
5.res目录:该目录用来存放程序这用到的图片、界面布局文件及XML格式的描述文件。该目录下有多个目录。新建一个Android项目,在res目录下一般
会有drawable,layout,valuse三个目录。drawable用来存放图片资源,目录下一般会有三个目录分别存放高中低三种不同分辨率的图片,layout目录用来存放应用程序的界面布局文件,values目录下存放字符串资源,颜色资源,数组资源等XML文件。
6.AndroidManifest.xml
18. 你如何评价Android系统?优缺点。
答:Android平台手机 5大优势: 
一、开放性 
在优势方面,Android平台首先就是其开发性,开发的平台允许任何移动终端厂商加入到Android联盟中来。显著的开放性可以使其拥有更多的开发 者,随着用户和应用的日益丰富,一个崭新的平台也将很快走向成熟。开放性对于Android的发展而言,有利于积累人气,这里的人气包括消费者和厂商,而 对于消费者来讲,随大的受益正是丰富的软件资源。开放的平台也会带来更大竞争,如此一来,消费者将可以用更低的价位购得心仪的手机。
二、挣脱运营商的束缚 
在过去很长的一段时间,特别是在欧美地区,手机应用往往受到运营商制约,使用什么功能接入什么网络,几乎都受到运营商的控制。从去年iPhone 上市 ,用户可以更加方便地连接网络,运营商的制约减少。随着EDGE、HSDPA这些2G至3G移动网络的逐步过渡和提升,手机随意接入网络已不是运营商口中 的笑谈,当你可以通过手机IM软件方便地进行即时聊天时,再回想不久前天价的彩信和图铃下载业务,是不是像噩梦一样?互联网巨头Google推动的 Android终端天生就有网络特色,将让用户离互联网更近。
三、丰富的硬件选择 
这一点还是与Android平台的开放性相关,由于Android的开放性,众多的厂商会推出千奇百怪,功能特色各具的多种产品。功能上的差异和特色,却 不会影响到数据同步、甚至软件的兼容,好比你从诺基亚 Symbian风格手机 一下改用苹果 iPhone ,同时还可将Symbian中优秀的软件带到iPhone上使用、联系人等资料更是可以方便地转移,是不是非常方便呢?
四、不受任何限制的开发商 
Android平台提供给第三方开发商一个十分宽泛、自由的环境,不会受到各种条条框框的阻扰,可想而知,会有多少新颖别致的软件会诞生。但也有其两面性,血腥、暴力、情色方面的程序和游戏如可控制正是留给Android难题之一。
五、无缝结合的Google应用 
如今叱诧互联网的Google已经走过10年度历史,从搜索巨人到全面的互联网渗透,Google服务如地图、邮件、搜索等已经成为连接用户和互联网的重要纽带,而Android平台手机将无缝结合这些优秀的Google服务。
Android的5大不足:
一、安全和隐私 
由于手机与互联网的紧密联系,个人隐私很难得到保守。除了上网过程中经意或不经意留下的个人足迹,Google这个巨人也时时站在你的身后,洞穿一切,因此,互联网的深入将会带来新一轮的隐私危机。
二、首先开卖Android手机的不是最大运营商 
众所周知,T-Mobile在23日,于美国纽约发布 了Android首款手机G1。但是在北美市场,最大的两家运营商乃AT&T和Verizon,而目前所知取得Android手机销售权的仅有 T-Mobile和Sprint,其中T-Mobile的3G网络相对于其他三家也要逊色不少,因此,用户可以买账购买G1,能否体验到最佳的3G网络服 务则要另当别论了!
三、运营商仍然能够影响到Android手机 
在国内市场,不少用户对购得移动定制机不满,感觉所购的手机被人涂画了广告一般。这样的情况在国外市场同样出现。Android手机的另一发售运营商Sprint就将在其机型中内置其手机商店程序。
四、同类机型用户减少 
在不少手机论坛都会有针对某一型号的子论坛,对一款手机的使用心得交流,并分享软件资源。而对于Android平台手机,由于厂商丰富,产品类型多样,这 样使用同一款机型的用户越来越少,缺少统一机型的程序强化。举个稍显不当的例子,现在山寨机泛滥,品种各异,就很少有专门针对某个型号山寨机的讨论和群 组,除了哪些功能异常抢眼、颇受追捧的机型以外。
五、过分依赖开发商缺少标准配置 
在使用PC端的Windows Xp系统的时候,都会内置微软Windows Media Player这样一个浏览器程序,用户可以选择更多样的播放器,如Realplay或暴风影音等。但入手开始使用默认的程序同样可以应付多样的需要。在 Android平台中,由于其开放性,软件更多依赖第三方厂商,比如Android系统的SDK中就没有内置音乐 播放器,全部依赖第三方开发,缺少了产品的统一性。
19.类似Android或IOS,他们都有一个共同的特点,那就是进程都是系统去关闭;而android的进程的5个等级是什么。

 Foreground

 正处于Activity Resume()状态

 正处于与bound服务交互的状态

 正处于服务在前台运行的状态(startForeground()被调用)

Service生命周期函数正在被执行(oncreate),onStart(),onDestroy()

BroadCastReceiver正在执行onReceiver();

杀死Foreground Process需要用户响应,因为这个安全优先级是最高的 

Visible Process

Activity不在前端显示,但也没有完全隐藏,能够看得见,比如弹出的dialog。 

Service Process

正在运行的,不在上述两种状态的Service

Background Process

不可见状态的Activity进程(onstop()被调用)

Empty Process

没有运行任何Components的进程,保留这个进程主要是为了缓存的需要

20.Android中asset文件夹和raw文件夹区别?

答:res/raw和assets的相同点:
两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
1)res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.raw.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2)res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
3)读取文件资源举例:
读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
InputStreamis=getResources().openRawResource(R.raw.filename);
读取assets下的文件资源,通过以下方式获取输入流来进行写操作

        
  1. AssetManager am=null;
  2. am=getAssets();
  3. InputStreamis=am.open("filename");

21.掌握模拟器的使用以及常用adb命令
1. adb devices
查看当前连接设备
2. adb kill-server
终止adb进程
3. adb start-server
启动adb进程
4. adb shell
进入shell模式(Linux模式),当连接有多个设备时,需执行命令
adb -s设备名shell
注:进入shell模式后序执行Linux命令
5. adb install apk路径
安装apk至设备,当连接有多个设备时,需执行命令
adb -s设备名install apk路径
当设备之前装有次apk时,替换安装序执行命令
adb install -r apk路径
6. adb uninstall要卸载的应用包名
卸载已安装的应用
7. adb push要拷贝的文件路径设备上存放次文件的路径
将文件拷贝至设备sdcard,如adb push F:\Android授课资料\项目实训\1205A\apk\com.moluo.android_100111.apk /sdcard
8. adb pull设备上文件路径电脑存放文件路径
将文件从设备拷贝到电脑,如adb pull /sdcard/com.moluo.android_100111.apk E:/
9. adb logcat
命令行的方式查看日志
若希望将日志保存至某文件,adb logcat -> E:/test.txt
10. android list avd
查看当前创建的所有模拟器列表
11. emulator @模拟器名字
启动某个模拟器
12.命令行操作数据库
adb shell
cd data/data
cd package
cd databases/cd shared_prefs/ cd files
sqlite3 test.db
>.tables
即可执行响应sql语句
22.掌握Activity的生命周期及各方法调用时机
答:共有七个周期函数:
void onCreate(BundlesavedInstanceState)第一次创建时调用
void onStart()被用户可见时调用
void onRestart()当Activity处于stop状态又被重新启动时调用
void onResume()当获得焦点即可与用户交互时调用
void onPause()当失去焦点时调用
void onStop()当不可见时调用
void onDestroy()当销毁时调用
Activity A---> Activity B, B将A完全覆盖时生命周期调用流程:
onPause(A) --> onCreate(B) --> onStart(B) --> onResume(B) --> onStop(A)
此时按"Back"按键,证明周期调用流程
onPause(B) --> onRestart(A) --> onStart(A) -->onResume(A) --> onStop(B) --> onDestroy(B)
23.Activity四种启动模式
在AndroidManifest.xml清单文件中的标签中通过android:launchMode设置Activity启动模式
standard:默认值,表示在startActivity时即创建其实例
singleTop:单一栈顶模式,首先检查栈顶是否有该Activity实例,有则返回,无则创建其实例
singleTask:单一任务模式,检查整个堆栈有无该Activity实例,有则返回,无则创建其实例
singleInstance:单一实例模式,一个Activity实例独享一个任务堆栈,并且只能有一个堆栈中有该Activity的实例
24.谈谈UI中,Padding和Margin有什么区别,gravity与layout_gravity的区别
答:Padding用来指定组件内的内容距离组件边界的距离;
Margin用来指定控件与控件之间的距离
Gravity用来指定组件内的内容相对于组件本身的位置
Layout_gravity用来指定组件相对于其父组件的位置
25.listview优化策略?
答:1)自定义Adapter的getView(),对convetView进行判空,是当convertView不为空的时候直接重新使用convertView
从而减少了很多不必要的View的创建
2)定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可
3)当ListView加载数据量较大时可以采用分页加载和图片异步加载
4)实现分页加载
实现OnScrollListener接口重写onScrollStateChanged和onScroll方法,使用onscroll方法实现”滑动“后处理检查是否还有新的记录,如果有,添加记录到adapter,adapter调用notifyDataSetChanged更新数据;如果没有记录了,则不再加载数据。使用onScrollStateChanged可以检测是否滚到最后一行且停止滚动然后执行加载.
5)异步加载图片
1.先从内存缓存中获取图片显示(内存缓冲)
2.获取不到的话从SD卡里获取(SD卡缓冲,,从SD卡获取图片是放在子线程里执行的,否则快速滑屏的话会不够流畅)
3.都获取不到的话从网络下载图片并保存到SD卡同时加入内存并显示(视情况看是否要显示)
26.view有哪几种更新方式
答:在主线程(UI线程)可以直接调用View.invalidate() ;
在子线程需要更新UI可以直接调用View.postInvalidate(),也可以通过Handler发送消息给主线程,然后在handleMessage方法中通过View.invalidate()更新UI;
还可以在子线程中需要更新UI的时候调用runOnUIThread(Runnable )方法,然后在此方法中更新UI,同时可以使用AsyncTask异步任务, 在doInBackground执行耗时操作,然后在onPostExcute方法中执行刷新UI动作
27.Intent的原理,作用,可以传递哪些类型的参数?
答:intent是连接Activity,Service,BroadcastReceiver,ContentProvider四大组件的信使,,可以传递八种基本数据类型以及string,Bundle类型,以及实现了Serializable或者Parcelable的类型。
Intent可以划分成显式意图和隐式意图。
显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。
隐式意图:没有明确指定组件名的Intent为隐式意图。Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。
28.Android的四大组件是什么?它们的作用是什么?
答:Android有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。
Activity:应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。
Service服务:一个Service是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。
BroadcastReceive广播接收器:你的应用可以使用它对外部事件进行过滤只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息。
ContentProvider内容提供者:主要用于多个应用间数据共享。这些数据可以存储在文件系统中或SQLite数据库。
29.DVM与JVM区别

· 区别一:dvm执行的是.dex格式文件,jvm执行的是.class文件。android程序编译完之后生产.class文件,然后,dex工具会把.class文件处理成.dex文件,然后把资源文件和.dex文件等打包成.apk文件。apk就是android package的意思。jvm执行的是.class文件。

· 区别二:dvm是基于寄存器的虚拟机而jvm执行是基于虚拟栈的虚拟机。寄存器存取速度比栈快的多,dvm可以根据硬件实现最大的优化,比较适合移动设备。

· 区别三:.class文件存在很多的冗余信息,dex工具会去除冗余信息,并把所有的.class文件整合到.dex文件中。减少了I/O操作,提高了类的查找速度。



















已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页